I want to:
- remove all empty nodes with no or all empty attributes f.e.
<node/>,<node attr1="" attr2=""/>, <node></node> - keep those nodes, which has at least one non-empty attribute f.e.
<node attr1="123" attr2="" attr3=""/>and then remove those empty attributes to have<node attr1="123"/>
- UPDATED keep those empty nodes, which have at least one non-empty child nodes, or which have at least one node with some attributes
EXAMPLE
Before
<a>
<b>
<c attr="1"/>
<d/>
</b>
</a>
After
<a>
<b>
<c attr="1"/>
</b>
</a>
I have following XSLT:
<xsl:template match="@*|node()">
<xsl:if test="normalize-space(.) != '' or ./@* != ''">
<xsl:copy>
<xsl:copy-of select = "@*[.!='']"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
</xsl:template>
It works pretty good, BUT only if my XML has at least one non-empty node! Example:
XML:
<ns1:form xmlns:ns1="http://aaa.com">
<ns1:test>
<a></a>
<b attr1=""/>
<c attr="123"/>
<d attr="">
<e attr="12">NOT EMPTY NODE</e>
</d>
</ns1:test>
</ns1:form>
After:
<?xml version="1.0" encoding="UTF-8"?><ns1:form xmlns:ns1="http://aaa.com">
<ns1:test>
<c attr="123"/>
<d>
<e attr="12">NOT EMPTY NODE</e>
</d>
</ns1:test>
</ns1:form>
Works fine, but skipping this non-empty node :
<ns1:form xmlns:ns1="http://aaa.com">
<ns1:test>
<a></a>
<b attr1=""/>
<c attr="123"/>
<d attr="">
<e attr="12"></e>
</d>
</ns1:test>
</ns1:form>
the output is:
<?xml version="1.0" encoding="UTF-8"?>
Anyone has any idea why it works like this? My code :
TransformerFactory factory = TransformerFactory.newInstance();
InputStream in = new FileInputStream(new File("transform.xslt"));
Source xslt = new StreamSource(in);
Transformer transformer = factory.newTransformer(xslt);
Source text = new StreamSource(new File("input.xml"));
StringReader reader = new StringReader(xml);
Source text = new StreamSource(reader);
transformer.transform(text, new StreamResult(writer));
Cheers
UPDATE
After using your XSLT the output is:
<?xml version="1.0" encoding="UTF-8"?><ns1:form xmlns:ns1="http://aaa.com">
<ns1:test>
<c attr="123"/>
<d>
<e attr="12">e</e>
</d>
</ns1:test>
</ns1:form>
I wonder why there are empty spaces in my output.xml?
Generally speaking, empty node is a node, which
1) istelf has no attributes or all empty AND
2) has no value f.e. <a></a>, <b/> AND
3) has no children which carry any data (has no children which meet the requirements 1 and 2) Example explaining empty nodes:
<a>
<b attr="1">
</b>
<c>
<d attr="2">
<e> value </e>
<f></f>
</d>
</a>
a is not empty because it has child b with attribute attr="1" (it's enough, but it also has: x, xx, xxx)
b is not empty because it has non-empty attribute
c is not empty because it has d node with attribute attr="2" (x) and also has child e with some value (xxx)
d is not empty becuase it has non-empty attribute (xx)
e is not empty because it has a value (xxx)
f is empty