一个关于使用 xslt 1.0 的快速问题,您可能会帮助我。我有一个如下所示的输入 xml
<Root>
<FirstName>Bob</FirstName>
<LastName>Marley</LastName>
<ID>BM1234</ID>
<Songs>
<Song>
<EmptyElements></EmptyElements>
<SongName>No woman no cry</SongName>
<Year>1974</Year>
<album></album>
<studio></studio>
<rating></rating>
</Song>
</Songs>
</Root>
输出需要看起来像
<Root>
<FirstName>Bob</FirstName>
<LastName>Marley</LastName>
<ID>BM1234</ID>
<Songs>
<Song>
<EmptyElements>album, studio, rating</EmptyElements>
<SongName>No woman no cry</SongName>
<Year>1974</Year>
</Song>
</Songs>
</Root>
所以基本上是将所有空元素的逗号分隔列表放入 EmptyElements 标记中。
最佳答案
或者简单地说:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Song">
<xsl:copy>
<EmptyElements>
<xsl:for-each select="*[not(node() or self::EmptyElements)]">
<xsl:value-of select="name()"/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</EmptyElements>
<xsl:apply-templates select="*[node()]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
注意事项:
这个解决方案自豪地使用了 last()
函数。没有与使用此功能相关的性能问题。
XPath 规范指出:
The last function returns a number equal to the context size from the expression evaluation context.
XSLT 规范告诉我们:
Expression evaluation occurs with respect to a context. ... The context consists of:
• a node (the context node)
• a pair of non-zero positive integers (the context position and the context size)
...
处理器将返回并为列表中的每个节点一次又一次地计算当前节点列表中的所有节点的想法简直是荒谬的。一旦建立了上下文(通过调用 xsl:for-each
或 xsl:apply-templates
),上下文大小就已知并且不会改变。
这个结论也可以很容易地进行测试:使用 10k 项的列表,在评估时没有发现明显的差异:
<xsl:for-each select="item">
<xsl:value-of select="position()!=last()"/>
</xsl:for-each>
反对:
<xsl:for-each select="item">
<xsl:value-of select="not(position() = 1)"/>
</xsl:for-each>
(使用 libxslt、Xalan 和 Saxon 测试)。
关于xml - xslt 1.0 合并空元素名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29908609/