我的输入xml文件如下:
<root>
<Property>
<Name>Jack</Name>
<Color>red.green</Color>
</Property>
<Property>
<Name>Jill</Name>
<Color>red.blue</Color>
</Property>
<Property>
<Name>Jim</Name>
<Color>red.orange</Color>
</Property>
<Property>
<Name>Tom</Name>
<Color>black.brown</Color>
</Property>
.
.
.
<Property>
<Name>Tom</Name>
<Color>white</Color>
</Property>
</root>
在XSLT 1.0中,我想选择其元素值之前的所有Property元素。是相同的,并在之前使相同的值。作为一个记录。
示例(使用示例子输入文件) 1)input.xml
<root>
<Property>
<Name>Jack</Name>
<Color>red.green</Color>
</Property>
<Property>
<Name>Jill</Name>
<Color>red.blue</Color>
</Property>
<Property>
<Name>Jim</Name>
<Color>red.orange</Color>
</Property>
</root>
sample sub output.xml
<red>
<green>Jack<green>
<blue>Jill<blue>
<orange>Jim<orange>
<red>
2)input.xml
<root>
<Property>
<Name>Jack</Name>
<Color>red.green</Color>
</Property>
<Property>
<Name>Jill</Name>
<Color>green.orange</Color>
</Property>
<Property>
<Name>Jim</Name>
<Color>orange.red</Color>
</Property>
<Property>
<Name>Ted</Name>
<Color>brown</Color>
</Property>
</root>
sample sub output.xml
<red>
<green>Jack</green>
</red>
<green>
<orange>Jill<orange>
</green>
<orange>
<red>Jim</red>
</orange>
<brown>Ted</brown>
我在stackoverflow本身问了类似的问题,但我对这些语句感到困惑,比如
<xsl:apply-templates select="/root/Property[generate-id(.) = generate-id(key('test',Property)[1])]"/>
其中键是:
<xsl:key name='test' match='Property' use='.'/>
[这里还有一个问题:密钥的匹配值应该作为Property或root / Property给出。我认为该键根据上下文选择Property元素。 (这里的上下文是/ root / Property,因为它是语句<xsl:apply-templates select="/root/Property)
中给出的XPATH表达式。这是真的请清楚这一点。]
我的实际关注点是
而不是使用它:
<xsl:apply-templates select="/root/Property[generate-id(.) = generate-id(key('test',Property)[1])]"/>
我可以用这个:
<xsl:apply-templates select="key('test',//root/Property)"/>
其中key是
<xsl:key name='test' match='Property' use='.'/>
实际差异(执行和流程)是什么?
答案 0 :(得分:2)
指令
<xsl:apply-templates select="key('test',//root/Property)"/>
获取所有Property元素,提取它们的值,然后为每个值查找具有该值的所有Property元素;然后它消除了重复;所以最终结果是你通过一条非常冗长的路线找到了所有的Property元素。
指令
<xsl:apply-templates
select="/root/Property[generate-id(.) = generate-id(key('test',Property)[1])]"/>
也不正确,除非你的Property元素有孩子叫Property,这似乎不太可能。我想你打算
<xsl:apply-templates
select="/root/Property[generate-id(.) = generate-id(key('test',.)[1])]"/>
这样做是为了选择一个Property元素,如果它的标识符(generate-id)与具有该值的第一个Property元素的标识符相同。换句话说:对于输入中的每个属性值,都有一组具有该值的Property元素,这样做的目的是选择每个组中的第一个元素。
如果您仍然无法理解它,请尝试转移到XSLT 2.0,其中分组变得更加简单。