使用 XSLT 删除具有 empty/no 属性的空节点
Removing empty nodes with empty/no attributes using XSLT
我想:
- 删除所有没有或所有空属性的空节点f.e。
<node/>
、<node attr1="" attr2=""/>, <node></node>
- 保留那些至少有一个 non-empty 属性的节点 f.e。
<node attr1="123" attr2="" attr3=""/>
然后删除那些空属性以获得 <node attr1="123"/>
- UPDATED 保留那些至少有一个 non-empty child 个节点的空节点,或者至少有一个具有某些属性的节点
示例
之前
<a>
<b>
<c attr="1"/>
<d/>
</b>
</a>
之后
<a>
<b>
<c attr="1"/>
</b>
</a>
我有以下 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>
效果很好,但前提是我的 XML 至少有一个 non-empty 节点!
示例:
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>
之后:
<?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>
工作正常,但跳过此 non-empty 节点:
<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>
输出是:
<?xml version="1.0" encoding="UTF-8"?>
有人知道为什么会这样吗?我的代码:
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));
干杯
更新
使用 XSLT 后输出为:
<?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>
我想知道为什么我的 output.xml 中有空格?
一般来说,空节点就是一个节点,即
1) istelf 没有属性或全为空 AND
2) 没有值 f.e。 <a></a>
、<b/>
和
3) has no children which carried any data (has no children 满足条件1和2)
解释空节点的示例:
<a>
<b attr="1">
</b>
<c>
<d attr="2">
<e> value </e>
<f></f>
</d>
</a>
a 不为空,因为它有 child b
和属性 attr="1"
(足够了,但它还有:x, xx, xxx)
b 不为空,因为它具有 non-empty 属性
c 不为空,因为它有 d
节点和属性 attr="2"
(x) 并且还有 child e
和一些值 (xxx)
d 不为空,因为它具有 non-empty 属性 (xx)
e 不为空,因为它有一个值 (xxx)
f 为空
您不应使 <xsl:apply-templates/>
成为条件 - 否则样式表将在第一个不满足条件的节点处停止,并且永远不会到达其子节点。
顺便说一句,如果正确理解您的条件,您可以将其简化为:
<xsl:template match="*[string() or @*[string()]]">
<xsl:copy>
<xsl:copy-of select = "@*[string()]"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
我想:
- 删除所有没有或所有空属性的空节点f.e。
<node/>
、<node attr1="" attr2=""/>, <node></node>
- 保留那些至少有一个 non-empty 属性的节点 f.e。
<node attr1="123" attr2="" attr3=""/>
然后删除那些空属性以获得<node attr1="123"/>
- UPDATED 保留那些至少有一个 non-empty child 个节点的空节点,或者至少有一个具有某些属性的节点
示例
之前
<a>
<b>
<c attr="1"/>
<d/>
</b>
</a>
之后
<a>
<b>
<c attr="1"/>
</b>
</a>
我有以下 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>
效果很好,但前提是我的 XML 至少有一个 non-empty 节点! 示例:
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>
之后:
<?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>
工作正常,但跳过此 non-empty 节点:
<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>
输出是:
<?xml version="1.0" encoding="UTF-8"?>
有人知道为什么会这样吗?我的代码:
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));
干杯
更新
使用 XSLT 后输出为:
<?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>
我想知道为什么我的 output.xml 中有空格?
一般来说,空节点就是一个节点,即
1) istelf 没有属性或全为空 AND
2) 没有值 f.e。 <a></a>
、<b/>
和
3) has no children which carried any data (has no children 满足条件1和2) 解释空节点的示例:
<a>
<b attr="1">
</b>
<c>
<d attr="2">
<e> value </e>
<f></f>
</d>
</a>
a 不为空,因为它有 child b
和属性 attr="1"
(足够了,但它还有:x, xx, xxx)
b 不为空,因为它具有 non-empty 属性
c 不为空,因为它有 d
节点和属性 attr="2"
(x) 并且还有 child e
和一些值 (xxx)
d 不为空,因为它具有 non-empty 属性 (xx)
e 不为空,因为它有一个值 (xxx)
f 为空
您不应使 <xsl:apply-templates/>
成为条件 - 否则样式表将在第一个不满足条件的节点处停止,并且永远不会到达其子节点。
顺便说一句,如果正确理解您的条件,您可以将其简化为:
<xsl:template match="*[string() or @*[string()]]">
<xsl:copy>
<xsl:copy-of select = "@*[string()]"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>