जावा: ट्रांसफॉर्मर द्वारा निर्मित XML का इंडेंट कैसे करें


112

मैं DOM के डॉक्यूमेंट लेने के लिए XML में निर्मित जावा का उपयोग कर रहा हूँ और परिणामी XML को प्रिंट कर रहा हूँ। समस्या यह है कि यह स्पष्ट रूप से पैरामीटर "इंडेंट" सेट करने के बावजूद पाठ को इंडेंट नहीं कर रहा है।

नमूना कोड

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>

विचार?

जवाबों:


215

आपको 'INDENT' को सक्षम करने और ट्रांसफार्मर के लिए इंडेंट राशि निर्धारित करने की आवश्यकता है:

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

अपडेट करें:


संदर्भ: क्रमांकन से पहले एक डोम से व्हाट्सएप-केवल टेक्स्ट नोड्स कैसे छीनें?

(सभी सदस्यों को विशेष रूप से @ marc-novakowski, @ james-murty और @saad के लिए बहुत धन्यवाद) :


70
मुझे मूर्खतापूर्ण लगता है कि डिफ़ॉल्ट इंडेंटेशन 0 है, लेकिन इसके अलावा INDENT=yesमुझे यह भी जोड़ना था:t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
लैपो

1
खबरदार। यह इंडेंटेशन प्रॉपर्टी जावा 5 में काम नहीं करती है। यह जावा 7 में काम करती है। जावा 6 में कोशिश नहीं की गई है
हिल्कियस

4
यदि आंतरिक नोड्स हैं जो कई लाइनें हैं, तो क्या आप आंतरिक हिस्से को भी इंडेंट कर सकते हैं? बस इस का उपयोग आंतरिक नोड्स इंडेंट नहीं करता है।
ईपार्क

1
@eipark with stackoverflow.com/a/979606/837530 , मैंने व्हाट्सएप को हटा दिया, और अब एक आकर्षण की तरह संकेत देता है
Sa'ad

1
@ लेपो यदि आपका प्रदाता xalan है (जो कि शायद यह काम करता है), तो यह उपलब्ध हैorg.apache.xml.serializer.OutputPropertiesFactory.S_KEY_INDENT_AMOUNT
OrangeDog

21

सुझाए गए समाधानों में से किसी ने भी मेरे लिए काम नहीं किया। इसलिए मैं एक वैकल्पिक समाधान खोजता रहा, जो कि उल्लेख से पहले दोनों का मिश्रण था और तीसरा चरण था।

  1. इंडेंट-नंबर को ट्रांसफार्मरफैक्ट्री में सेट करें
  2. ट्रांसफार्मर में इंडेंट को सक्षम करें
  3. एक लेखक (या बफ़रेड राइटर) के साथ ओटपुटस्ट लपेटें
//(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

(यदि मैंने अपने स्रोत को गलत तरीके से उद्धृत किया है तो कृपया मुझे बताएं)


3
अंतिम पंक्ति में "आउट" क्या है?
मुजीमु

क्या आपको एक निर्माता का उपयोग करके एक नया पूर्णांक बनाने की आवश्यकता है?
बेंजीनर

मैं अनुमान लगा रहा हूं क्योंकि आपका प्रदाता Xalan नहीं है। क्या आप जांच सकते हैं कि आपका TransformerFactoryवास्तव में ऐसा क्या है जो अन्य लोग जानते हैं।
ऑरेंजडॉग

चरण 3, Writerआउटपुट के रूप में उपयोग करना आवश्यक है।
इरिकसन

14

निम्नलिखित कोड मेरे लिए जावा 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 की टिप्पणी मददगार साबित हुई।


8

आयात com.sun.org.apache.xml.internal.serializer.OutputPropertiesFactory

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

यह एक आंतरिक वर्ग है, इसलिए आपका कोड अन्य (या यहां तक ​​कि नए) जेवीएम के लिए पोर्टेबल नहीं होगा।
ऑरेंजडॉग

5

यदि आप इंडेंटेशन चाहते हैं, तो आपको इसे निर्दिष्ट करना होगा TransformerFactory

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

4

मैंने ट्रांसफॉर्मर के साथ खिलवाड़ करने के बजाय 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);

हाँ। मैंने ट्रांसफार्मर के साथ अन्य सभी तरीकों की कोशिश की, लेकिन सभी टूट गए। संपूर्ण W3C पुस्तकालय एक गड़बड़ है। Xerces ने काम किया।
Tuntable

3

मुझे जोड़ने के लिए DOCTYPE_PUBLICकाम किया:

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

transformer.setOutputProperty (OutputKeys.DOCTYPE_PUBLIC, "हाँ"); यह कुंजी है
मौनव्रत
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.