我有一个XML文件,其结构类似于
<?xml version="1.0"?>
<medias>
<media>
<id>34500</id>
<refid/>
</media>
<media>
<id>34501</id>
<refid>34500</refid>
</media>
<media>
<id>34502</id>
<refid>34500</refid>
</media>
<media>
<id>34503</id>
<refid>34501</refid>
</media>
<media>
<id>34504</id>
<ref/>
</media>
<media>
<id>34505</id>
<refid>34502</refid>
</media>
</medias>
使用XSL 1.0,我想访问其他未引用的节点。 所以我创建了两个变量
<xsl:variable name="origID" select="media/id/text()"/>
<xsl:variable name="refID" select="media/refid/text()"/>
并查看了如何在这两个元素集之间执行差异操作
<xsl:variable name="diffID" select="$origID[count(. | $refID) != count($refID)]"/>
结果是:
origID包含34500,34501,34502,34503,34504,34505
refID包含34500,34500,34501,34502
我期待
diffID将包含34503,34504,34505
但是
diffID仍包含34500,34501,34502,34503,34504,34505。
实现我的目标的最佳方法是获取ID被其他节点引用的所有节点。
提前致谢
安德烈
答案 0 :(得分:1)
要将refid未引用的id转换为变量,您可以尝试这样做:
<xsl:variable name="diffID" select="media[not(id = //media/refid)]/id"/>
要证明它有效:
<xsl:template match="/*">
<xsl:variable name="diffID" select="media[not(id = //media/refid)]/id"/>
<xsl:for-each select="$diffID" >
<xsl:value-of select="."/>
<xsl:text>, </xsl:text>
</xsl:for-each>
</xsl:template>
这将产生以下输出。
34503, 34504, 34505,
如果真实文件要大得多,则应使用xsl:key
对变量中的id做同样的事情:
<xsl:template match="/*">
<xsl:variable name="origID" select="media/id"/>
<xsl:variable name="refID" select="media/refid"/>
<xsl:variable name="diffID" select="$origID[not(. = $refID)]"/>
<xsl:for-each select="$diffID" >
<xsl:value-of select="."/>
<xsl:text>, </xsl:text>
</xsl:for-each>
</xsl:template>
答案 1 :(得分:1)
使用XSLT 2.0,您可以使用except
运算符(只要您选择节点而不是原始值):
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="medias-with-id" select="//media[id]"/>
<xsl:variable name="referenced-medias" select="key('by-id', //refid)"/>
<xsl:key name="by-id" match="media" use="id"/>
<xsl:template match="/">
<xsl:copy-of select="$medias-with-id except $referenced-medias"/>
</xsl:template>
</xsl:stylesheet>