Removing Empty Attributes from XML

I have an xml buggy that contains empty attributes, and I have a parser that coughs on empty attributes. I have no control over xml generation and over the parser that coughs on empty attrs. So what I want to do is a preprocessing step that simply removes all empty attributes.

I managed to find empty attributes, but now I do not know how to remove them:

   XPathFactory xpf = XPathFactory.newInstance();
   XPath xpath = xpf.newXPath();
   XPathExpression expr = xpath.compile("//@*");
   Object result = expr.evaluate(d, XPathConstants.NODESET);

   if (result != null) {
    NodeList nodes = (NodeList) result;
    for(int node=0;node<nodes.getLength();node++)
    {
     Node n = nodes.item(node);
     if(isEmpty(n.getTextContent()))
     {
      this.log.warn("Found empty attribute declaration "+n.toString());
      NamedNodeMap parentAttrs = n.getParentNode().getAttributes();
      parentAttrs.removeNamedItem(n.getNodeName());
     }
    }

   } 

This code gives me NPE when accessing n.getParentNode (). getAttributes (). But how can I remove an empty attribute from an element when I cannot access the element?

+3
source share
6 answers

- , . - . , , - , : .

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@*[normalize-space()='']"/>
</xsl:stylesheet>
+1

, XPATH:

//*[@*[.='']]

, :

//*[@*[normalize-space()='']].

, , , .

+3

, , . - NodeList XML. DOM, DOM , - , , .

, , XMLFilter . IBM Developerworks , , , .

, SAX-, - , SAX .

xslt.

+1

getParentNode() .

, Attr, Document, DocumentFragment, Entity Notation, .

100% , , , :

//*[@*]

,

0

, ATTR, Elements . XPathExpression, "//@*" " ", " " (, , ). , root node , [root node]. GetParentNode() == null NPE.

, , attr , n.getTextContent() , (- , NPE, node , ), , -op ( ).

, , , , , -, DOM .

0

I really found a way to do this. Although this does not solve the problem perfectly, it is OK at the moment. If you use this, be warned that it will only catch attributes that have a value, which is precisely "other nonsense, such as a value consisting only of spaces, will not be caught by this.

   XPathFactory xpf = XPathFactory.newInstance();
   XPath xpath = xpf.newXPath();
   XPathExpression expr = xpath.compile("//*[@*='']");
   Object result = expr.evaluate(d, XPathConstants.NODESET);

   if (result != null) {
    NodeList nodes = (NodeList) result;
    for(int node=0;node<nodes.getLength();node++)
    {
     Node n = nodes.item(node);
     NamedNodeMap attrs = n.getAttributes();
     for(int attr=0;attr<attrs.getLength();attr++)
     {
      Node a = attrs.item(attr);
      if(isEmpty(a.getNodeValue()));
      {
       attrs.removeNamedItem(a.getNodeName());
       this.log.warn("Removing empty attribute "+a.toString()+" from element "+n.getNodeName());
      }
     }
    }

   } 

What a pity for comparison is only available as an XSLT extension and is not provided for support on each XSLT processor: - (

0
source

Source: https://habr.com/ru/post/1737669/


All Articles