[java] 자바 : Transformer에서 생성 한 XML 들여 쓰기 방법

Java의 내장 XML 변환기를 사용하여 DOM 문서를 가져와 결과 XML을 인쇄하고 있습니다. 문제는 “indent”매개 변수를 명시 적으로 설정 했음에도 불구하고 텍스트를 전혀 들여 쓰지 않는다는 것입니다.

샘플 코드

public class TestXML {

 public static void main(String args[]) throws Exception {
  ByteArrayOutputStream s;

  Document d = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
  Transformer t = TransformerFactory.newInstance().newTransformer();

  Element a,b;

  a = d.createElement("a");
  b = d.createElement("b");

  a.appendChild(b);

  d.appendChild(a);

  t.setParameter(OutputKeys.INDENT, "yes");

  s = new ByteArrayOutputStream();

  t.transform(new DOMSource(d),new StreamResult(s));

  System.out.println(new String(s.toByteArray()));

 }
}

결과

<?xml version="1.0" encoding="UTF-8" standalone="no"?><a><b/></a>

원하는 결과

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<a>
 <b/>
</a>

생각?



답변

‘INDENT’를 활성화하고 변환기의 들여 쓰기 양을 설정해야합니다.

t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

최신 정보:


참조 : 직렬화 전에 DOM에서 공백 전용 텍스트 노드를 제거하는 방법은 무엇입니까?

(특히 @ marc-novakowski, @ james-murty 및 @saad 모든 회원에게 감사드립니다) :


답변

제안 된 솔루션 중 어느 것도 저에게 효과적이지 않았습니다. 그래서 나는 앞서 언급 한 두 가지와 세 번째 단계의 혼합이 된 대체 솔루션을 계속 찾았습니다.

  1. 트랜스포머 팩토리에 들여 쓰기 번호 설정
  2. 변압기에서 들여 쓰기 활성화
  3. otuputstream을 writer (또는 bufferedwriter)로 래핑합니다.
//(1)
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute("indent-number", new Integer(2));

//(2)
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");

//(3)
t.transform(new DOMSource(doc),
new StreamResult(new OutputStreamWriter(out, "utf-8"));

xml 처리 코드의 “버그”동작을 해결하려면 (3)을 수행해야합니다.

출처 : johnnymac75 @ http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6296446

(제 출처를 잘못 인용 한 경우 알려주세요)


답변

다음 코드는 Java 7에서 저에게 효과적입니다. 트랜스포머 (트랜스포머 팩토리가 아님)에 들여 쓰기 (예)와 들여 쓰기 양 (2)을 설정하여 작동하도록했습니다.

TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(source, result);

속성을 설정하는 @mabac의 솔루션이 저에게는 효과가 없었지만 @lapo의 의견은 도움이되었습니다.


답변

import com.sun.org.apache.xml.internal.serializer.OutputPropertiesFactory

transformer.setOutputProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "2");


답변

들여 쓰기를 원하면 TransformerFactory.

TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute("indent-number", new Integer(2));
Transformer t = tf.newTransformer();


답변

Transformer를 엉망으로 만드는 대신 Xerces (Apache) 라이브러리를 사용했습니다. 라이브러리를 추가하면 아래 코드를 추가하십시오.

OutputFormat format = new OutputFormat(document);
format.setLineWidth(65);
format.setIndenting(true);
format.setIndent(2);
Writer outxml = new FileWriter(new File("out.xml"));
XMLSerializer serializer = new XMLSerializer(outxml, format);
serializer.serialize(document);


답변

나를 DOCTYPE_PUBLIC위해 일 추가 :

transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,"yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "10");