我有以下问题:
在样式表文档中,我想从相对简单的xml文件创建输出。 虽然大多数常见的XPath和XSLT并不那么困难,但比较两个元素并决定,如何继续下去是一个很大的问题。
示例xml:
<root>
<foo>
<value>1</value>
<name>foo1</name>
</foo>
<foo>
<value>2</value>
<name></name>
</foo>
<foo>
<value>3</value>
<name>foo3</name>
</foo>
<bar>
<value>1</value>
</bar>
<bar>
<value>2</value>
</bar>
</root>
样式表中的是一个xsl:for循环,它试图决定是否显示当前节点:
[...]
<xsl:for-each select="bar">
<xsl:if test="//foo[value=./value]/name">
<!-- go on, if the content of the 'name' element is not empty -->
</xsl:if>
</xsl:for-each>
[...]
如果来自'foo'的'name'元素的内容不为空,则使用'value'元素的euqality,意图只是继续使用这些东西。 结果是,'bar'中的每一行都会创建一个输出事件,如果我打算不为第二个条目设置一个,因为'// foo [2] / name'为空。
我不确定,现在该怎么办......也许生成的密钥就足够了!?我不知道......
感谢您的每一条评论!
答案 0 :(得分:1)
使用密钥,例如
<xsl:key name="k1" match="foo" use="value"/>
作为xsl:stylesheet
的孩子然后
<xsl:for-each select="bar[normalize-space(key('k1', value)/name)]">...</xsl:for-each>
答案 1 :(得分:1)
您可能希望使用以下内容:
<xsl:template match="/">
<root>
<xsl:for-each select="//bar">
<xsl:for-each select="//foo[value=current()/value]">
<xsl:if test="name != ''">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</root>
</xsl:template>
最引人注目的当然是你应该使用current()/ value而不是./value,因为current()引用了bar元素,而且。指的是循环的foo元素。
当应用于提供的输入时,这将给出
<?xml version="1.0" encoding="UTF-8"?>
<root>
<foo>
<value>1</value>
<name>foo1</name>
</foo>
</root>