使用在<xsl:output> 声明中指定的indent="yes 的简单身份转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
此转换,当应用于提供的 XML 文档时(未定义的实体 &nbsp; 被其对应的字符实体 &#xA0; 替换):
<dtd name="cited">
<XMLDOC>
<cited year="2010">
<case>
No. 275 v. M.N.R.
<cite>
<yr>
2010
<pno cite="20101188">10</pno>
</yr>
</cite>
</case>
</cited>
</XMLDOC>
<XMLDOC>
<case>
Wellesley St.
<cite>
<yr>
2010
<pno cite="20105133">9</pno>
</yr>
</cite>
</case>
</XMLDOC>
</dtd>
使用 AltovaXML 运行时产生:
<dtd name="cited">
<XMLDOC>
<cited year="2010">
<case>
No. 275 v. M.N.R.
<cite>
<yr>
2010
<pno cite="20101188">10</pno></yr>
</cite></case>
</cited>
</XMLDOC>
<XMLDOC>
<case>
Wellesley St.
<cite>
<yr>
2010
<pno cite="20105133">9</pno></yr>
</cite></case>
</XMLDOC>
</dtd>
使用 Saxon 6.5.4 运行时,同样的转换会产生:
<dtd name="cited">
<XMLDOC>
<cited year="2010">
<case>
No. 275 v. M.N.R.
<cite>
<yr>
2010
<pno cite="20101188">10</pno>
</yr>
</cite>
</case>
</cited>
</XMLDOC>
<XMLDOC>
<case>
Wellesley St.
<cite>
<yr>
2010
<pno cite="20105133">9</pno>
</yr>
</cite>
</case>
</XMLDOC>
</dtd>
因此,输出有很大不同,具体取决于所使用的 XSLT 1.0 处理器。 Saxon 解析并且不会丢弃每个仅空白节点,这加上缩进会产生过多的空白。
解决方法是使用以下方法显式地去除纯空白节点:
<xsl:strip-space elements="*"/>
所以,当这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用 Saxon 对同一个源 XML 文档运行,现在的输出是:
<dtd name="cited">
<XMLDOC>
<cited year="2010">
<case>
No. 275 v. M.N.R.
<cite>
<yr>
2010
<pno cite="20101188">10</pno>
</yr>
</cite>
</case>
</cited>
</XMLDOC>
<XMLDOC>
<case>
Wellesley St.
<cite>
<yr>
2010
<pno cite="20105133">9</pno>
</yr>
</cite>
</case>
</XMLDOC>
</dtd>
AltovaXML 和许多其他 XSLT 1.0 处理器(.NET 的 XslCompiledTransform、XslTransform)在运行最后一个转换时也会产生很好的缩进输出。
更新:
就在最近在他的cmets中,OP泄露了重要的新要求,这使得这个问题完全不仅仅是“缩进”......
来自 cmets:
我想要的是应用正确的
结束标签,如
<yr></yr>
<pno cite="20101188">10</pno>
而不是
<yr>
2010
<pno cite="20101188">10</pno>
</yr>
这是产生所需输出的转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="yr">
<yr>
<xsl:apply-templates select="text()[1]"/>
</yr>
<xsl:apply-templates select="*"/>
</xsl:template>
</xsl:stylesheet>