xslt根据属性值获取第n个兄弟

时间:2012-07-09 21:47:03

标签: xslt

我需要根据属性值及其在xml文档中的位置,将xml节点添加到输出文档中的特定位置。

在下面的示例中,每次出现product =“111”时,我需要获得product =“222”的子项的相应路径属性。需要注意的是:他们在文档中的相对位置必须匹配。对于第一个产品=“111”,我将需要第一个产品的路径=“222”。对于第二个“111”,我将需要第二个产品“222”的路径。

我需要的输出(我也添加了当前产品的路径,但没有问题):

<output>
    <product_out id="111">
        <path>b</path>
    </product_out>
    <product_out id="111">
        <path>g</path>
    </product_out>
    <product_out id="111">
        <path>i</path>
    </product_out>
</output>

我的xml文档。

<?xml version="1.0"?>
<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<item product="111">
    <sub_item path="a" />
</item>
<item product="222">
    <sub_item path="b" />
</item>
<item product="333">
    <sub_item path="c" />
</item>
<item product="111">
    <sub_item path="d" />
</item>
<item product="111">
    <sub_item path="e" />
</item>
<item product="555">
    <sub_item path="f" />
</item>
<item product="222">
    <sub_item path="g" />
</item>
<item product="555">
    <sub_item path="h" />
</item>
<item product="222">
    <sub_item path="i" />
</item>
</order>

我的xsl文件:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="/">
<output>
    <xsl:apply-templates />
</output>
</xsl:template>

<xsl:template match="order/item">
<product_out>
    <xsl:attribute name="id"><xsl:value-of select="@product"/></xsl:attribute>

    <xsl:if test="@product = 111">
        <the_correct_sibling_position><xsl:value-of select="1+count(preceding-sibling::item[@product='111'])"/></the_correct_sibling_position>
        <path_test1><xsl:value-of select="/order/item[position()=4]/sub_item/@path"/></path_test1>
        <path_test2><xsl:value-of select="/order/item[2]/sub_item/@path"/></path_test2>
        <path_test3><xsl:value-of select="/order/item[position()=number(1+count(preceding-sibling::item[@product='111']))]/sub_item/@path"/></path_test3>
        <path_test4><xsl:value-of select="/order/item[position()=1+count(preceding-sibling::item[@product='111'])]/sub_item/@path"/></path_test4>
    </xsl:if>
    <path><xsl:value-of select="sub_item/@path[1]"/></path>
</product_out>
</xsl:template>
</xsl:stylesheet>

我可以使用

获得我需要的正确数组位置
  

1 +计数(前同辈::项[@产物= '111'])

我通过输出&lt; the_correct_sibling_position&gt; 节点中的值来测试。

我也可以硬编码节点位置:

path_test1 always returns d
path_test2 always returns b

接下来的两个测试不会像我期望的那样输出值b,g,i。

path_test3 always returns a
path_test4 always returns a

如何根据产品节点“111”“222”的位置获取返回b,g和i的路径? previous-sibling变量在我的select语句的路径中没有像我期望的那样工作。

请帮忙!

1 个答案:

答案 0 :(得分:1)

我重新测试了之前的一些尝试,它现在正在运行,不知道为什么之前没有。我添加了一个变量,然后在我的select语句中使用它。

变量代码:

<xsl:variable name="t1"><xsl:value-of select="1+count(preceding-sibling::item[@product='111'])"/></xsl:variable>

我的选择陈述:

        <path_test_good><xsl:value-of select="/order/item[@product='222'][position()= $t1]/sub_item/@path"/></path_test_good>