我有以下XML:
<nodes>
<node>
<articles>125,1,9027</articles>
</node>
<node>
<articles>999,48,123</articles>
</node>
<node>
<articles>123,1234,4345,567</articles>
</node>
</nodes>
我需要编写一些XSLT,它只返回具有paricular article id的节点,所以在上面的例子中,只有那些包含第123条的节点。
我的XSLT并不好,所以我正在努力解决这个问题。我想做这样的事情,但我知道XSLT中没有'instring'扩展方法:
<xsl:variable name="currentNodeId" select="1234"/>
<xsl:for-each select="$allNodes [instring(articles,$currentNodeId)]">
<!-- Output stuff -->
</xsl:for-each>
我知道这很黑,但不确定解决这个问题的最佳方法。节点集可能很大,节点内的文章ID数量也可能很大,所以我非常确定将节点的值拆分为一个节点集是不是'这将非常有效,但我可能是错的!
非常感谢任何有关最佳方法的帮助,谢谢。
答案 0 :(得分:1)
XSLT 2.0:这将匹配文本中完全 123的文章。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="id" select="123"/>
<xsl:template match="/">
<xsl:for-each select="//node[matches(articles, concat('(^|\D)', $id, '($|\D)'))]">
<xsl:value-of select="current()"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
示例输入:
<?xml version="1.0" encoding="utf-8"?>
<nodes>
<node>
<articles>1234,1000,9027</articles>
</node>
<node>
<articles>999,48,01234</articles>
</node>
<node>
<articles>123,1234,4345,567</articles>
</node>
<node>
<articles> 123 , 456 </articles>
</node>
</nodes>
输出:
123,1234,4345,567
123 , 456
我不知道如何有效地使用XSLT 1.0,但OP表示他正在使用XSLT 2.0,所以这应该是一个充分的答案。
答案 1 :(得分:0)
在XSLT 1.0中,您可以使用此简单解决方案,它使用normalize-space
,translate
,contains
,substring
,string-length
函数。
示例输入XML:
<nodes>
<node>
<articles>125,1,9027</articles>
</node>
<node>
<articles>999,48,123</articles>
</node>
<node>
<articles>123,1234,4345,567</articles>
</node>
<node>
<articles> 123 , 456 </articles>
</node>
<node>
<articles>789, 456</articles>
</node>
<node>
<articles> 123 </articles>
</node>
<node>
<articles>456, 123 ,789</articles>
</node>
</nodes>
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="id" select="123"/>
<xsl:template match="node">
<xsl:variable name="s" select="translate(normalize-space(articles/.), ' ', '')"/>
<xsl:if test="$s = $id
or contains($s, concat($id, ','))
or substring($s, string-length($s) - string-length($id) + 1, string-length($id)) = $id">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
<xsl:template match="/nodes">
<xsl:copy>
<xsl:apply-templates select="node"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出:
<nodes>
<node>
<articles>999,48,123</articles>
</node>
<node>
<articles>123,1234,4345,567</articles>
</node>
<node>
<articles> 123 , 456 </articles>
</node>
<node>
<articles> 123 </articles>
</node>
<node>
<articles>456, 123 ,789</articles>
</node>
</nodes>