2009-06-11 7 views
16

मैं कुछ जावा (5.0) कोड है कि विभिन्न (कैश्ड) डेटा स्रोतों से एक डोम निर्माण करती है, तो, कुछ तत्व नोड्स की आवश्यकता नहीं है निकालता है तो का उपयोग कर एक XML स्ट्रिंग में परिणाम को धारावाहिक:सीरियलाइजेशन से पहले एक डोम से व्हाइटस्पेस-केवल टेक्स्ट नोड्स को कैसे पट्टी करें?

// Serialize DOM back into a string 
Writer out = new StringWriter(); 
Transformer tf = TransformerFactory.newInstance().newTransformer(); 
tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
tf.setOutputProperty(OutputKeys.INDENT, "no"); 
tf.transform(new DOMSource(doc), new StreamResult(out)); 
return out.toString(); 

हालांकि , क्योंकि मैं कई तत्व नोड्स को हटा रहा हूं, इसलिए मैं अंतिम धारावाहिक दस्तावेज़ में बहुत से अतिरिक्त व्हाइटस्पेस के साथ समाप्त होता हूं।

क्या डीओएम से पहले (या थोड़ी देर) इसे स्ट्रिंग में क्रमबद्ध करने के लिए बाहरी सफेद जगह को हटाने/संक्षिप्त करने का कोई आसान तरीका है?

उत्तर

31

आप XPath का उपयोग कर रिक्त पाठ नोड्स पा सकते हैं, तो उन्हें प्रोग्राम के रूप में इतनी तरह हटा दें:

XPathFactory xpathFactory = XPathFactory.newInstance(); 
// XPath to find empty text nodes. 
XPathExpression xpathExp = xpathFactory.newXPath().compile(
     "//text()[normalize-space(.) = '']"); 
NodeList emptyTextNodes = (NodeList) 
     xpathExp.evaluate(doc, XPathConstants.NODESET); 

// Remove each empty text node from document. 
for (int i = 0; i < emptyTextNodes.getLength(); i++) { 
    Node emptyTextNode = emptyTextNodes.item(i); 
    emptyTextNode.getParentNode().removeChild(emptyTextNode); 
} 

यह दृष्टिकोण उपयोगी हो सकता है यदि आप एक्सएसएल टेम्पला के साथ आसानी से हासिल किए जाने से नोड हटाने पर अधिक नियंत्रण चाहते हैं ते।

+0

मुझे यह "कोड केवल" समाधान XSL समाधान से भी बेहतर पसंद है, और जैसा कि आपने कहा है कि यदि आवश्यक हो तो नोड हटाने पर थोड़ा अधिक नियंत्रण है। –

+2

वैसे, यह विधि केवल काम करने लगती है अगर मैं पहले नोड हटाने से पहले doc.normalize() को कॉल करता हूं। मुझे यकीन नहीं है कि इससे कोई फर्क क्यों पड़ता है। –

+3

उत्कृष्ट जवाब। सामान्य के बिना भी मेरे लिए काम करता है()। –

7

अपने डोम क्रमानुसार करने निम्नलिखित XSL और strip-space तत्व का उपयोग का प्रयास करें:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" omit-xml-declaration="yes"/> 

    <xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

http://helpdesk.objects.com.au/java/how-do-i-remove-whitespace-from-an-xml-document

+0

धन्यवाद! यह एक अच्छा जवाब है और मैंने कोशिश की .. और यह काम करता है। –

-3
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 

यह एक्सएमएल इंडेंटेशन बनाए रखेगा।

+1

यह अनावश्यक रिक्त स्थान नहीं छीनता है। –

4

नीचे कोड सभी खाली रिक्त स्थान के साथ टिप्पणी नोड्स और टेक्स्ट नोड हटा देता है। पाठ नोड कुछ मान है, तो मूल्य छंटनी की जाएगी

public static void clean(Node node) 
{ 
    NodeList childNodes = node.getChildNodes(); 

    for (int n = childNodes.getLength() - 1; n >= 0; n--) 
    { 
    Node child = childNodes.item(n); 
    short nodeType = child.getNodeType(); 

    if (nodeType == Node.ELEMENT_NODE) 
     clean(child); 
    else if (nodeType == Node.TEXT_NODE) 
    { 
     String trimmedNodeVal = child.getNodeValue().trim(); 
     if (trimmedNodeVal.length() == 0) 
      node.removeChild(child); 
     else 
      child.setNodeValue(trimmedNodeVal); 
    } 
    else if (nodeType == Node.COMMENT_NODE) 
     node.removeChild(child); 
    } 
} 

रेफरी: http://www.sitepoint.com/removing-useless-nodes-from-the-dom/

0

एक अन्य संभावित दृष्टिकोण के रूप में आप लक्ष्य नोड्स निकाल रहे हैं एक ही समय में पड़ोसी सफेद स्थान को निकालना है:

private void removeNodeAndTrailingWhitespace(Node node) { 
    List<Node> exiles = new ArrayList<Node>(); 

    exiles.add(node); 
    for (Node whitespace = node.getNextSibling(); 
      whitespace != null && whitespace.getNodeType() == Node.TEXT_NODE && whitespace.getTextContent().matches("\\s*"); 
      whitespace = whitespace.getNextSibling()) { 
     exiles.add(whitespace); 
    } 

    for (Node exile: exiles) { 
     exile.getParentNode().removeChild(exile); 
    } 
} 

यह शेष मौजूदा स्वरूपण को बरकरार रखने का लाभ है।

0

निम्नलिखित कोड काम करता है:

public String getSoapXmlFormatted(String pXml) { 
    try { 
     if (pXml != null) { 
      DocumentBuilderFactory tDbFactory = DocumentBuilderFactory 
        .newInstance(); 
      DocumentBuilder tDBuilder; 
      tDBuilder = tDbFactory.newDocumentBuilder(); 
      Document tDoc = tDBuilder.parse(new InputSource(
        new StringReader(pXml))); 
      removeWhitespaces(tDoc); 
      final DOMImplementationRegistry tRegistry = DOMImplementationRegistry 
        .newInstance(); 
      final DOMImplementationLS tImpl = (DOMImplementationLS) tRegistry 
        .getDOMImplementation("LS"); 
      final LSSerializer tWriter = tImpl.createLSSerializer(); 
      tWriter.getDomConfig().setParameter("format-pretty-print", 
        Boolean.FALSE); 
      tWriter.getDomConfig().setParameter(
        "element-content-whitespace", Boolean.TRUE); 
      pXml = tWriter.writeToString(tDoc); 
     } 
    } catch (RuntimeException | ParserConfigurationException | SAXException 
      | IOException | ClassNotFoundException | InstantiationException 
      | IllegalAccessException tE) { 
     tE.printStackTrace(); 
    } 
    return pXml; 
} 

public void removeWhitespaces(Node pRootNode) { 
    if (pRootNode != null) { 
     NodeList tList = pRootNode.getChildNodes(); 
     if (tList != null && tList.getLength() > 0) { 
      ArrayList<Node> tRemoveNodeList = new ArrayList<Node>(); 
      for (int i = 0; i < tList.getLength(); i++) { 
       Node tChildNode = tList.item(i); 
       if (tChildNode.getNodeType() == Node.TEXT_NODE) { 
        if (tChildNode.getTextContent() == null 
          || "".equals(tChildNode.getTextContent().trim())) 
         tRemoveNodeList.add(tChildNode); 
       } else 
        removeWhitespaces(tChildNode); 
      } 
      for (Node tRemoveNode : tRemoveNodeList) { 
       pRootNode.removeChild(tRemoveNode); 
      } 
     } 
    } 
} 
+0

यह उत्तर कुछ स्पष्टीकरण से लाभान्वित होगा। – Eiko

संबंधित मुद्दे