对于For循环和If语句中的循环

时间:2014-03-19 17:23:27

标签: xml xslt xslt-1.0

我有以下XML代码(这是我正在尝试使用的代码片段)。

 <products>
    <product>
        <productname>Name2</productname>   
        <productsize measurement="ml">250</productsize>
        <productsize measurement="ml">500</productsize>
        <productsize measurement="ml">750</productsize>
        <otherelements></otherelements>
        <price size="250" packsize="1">1.25</price>
        <price size="250" packsize="6">7.50</price>
        <price size="250" packsize="12">7.00</price>
        <price size="500" packsize="1">1.75</price>
        <price size="500" packsize="6">10.50</price>
        <price size="500" packsize="12">19.00</price>
        <price size="750" packsize="1">2.25</price>
        <price size="750" packsize="6">13.50</price>
        <price size="750" packsize="12">25.00</price>
    </product>
    <product>
        <productname>Name1</productname>   
        <productsize measurement="ml">250</productsize>
        <productsize measurement="ml">750</productsize>
        <otherelements></otherelements>
        <price size="250" packsize="1">1.25</price>
        <price size="250" packsize="6">7.50</price>
        <price size="250" packsize="12">7.00</price>
        <price size="750" packsize="1">2.25</price>
        <price size="750" packsize="6">13.50</price>
        <price size="750" packsize="12">25.00</price>
    </product>
 </products>

我要做的是像这样显示

250ml 1=£1.25, 6=£7.50, 12=£7.00
500ml 1=£1.75, 6=£10.50, 12=£19.00 
750ml 1=£2.25, 6=£13.50, 12=£25.00

但它没有工作,这是我的XSL代码我做错了什么,我知道它与内部for循环有关。

<xsl:for-each select="x:productsize">
<p>
   <xsl:value-of select="."/>
   <xsl:value-of select="@measurement"/>
</p>

   <xsl:for-each select="x:price">
   <xsl:if test="productsize = '@size'">
       <xsl:value-of select="."/>
   </xsl:if>
   </xsl:for-each>                                
</xsl:for-each>

2 个答案:

答案 0 :(得分:4)

首先,您的XML无效......您不能拥有名为<other elements></other elements>的元素。您的结束<product>应为</product>。但我想这只是写在那里的问题。

主要问题是<price>不在内<productsize> ...因此当您在<xsl:for-each>上运行productsize时,您正在有效地搜索/productsize/price <xsl:for-each select="product/productsize"> <xsl:variable name="sizevar" select="."/> <p> <xsl:value-of select="."/> <xsl:value-of select="@measurement"/> &#160; <xsl:for-each select="../price[@size=$sizevar]"> <xsl:value-of select="@packsize"/> = <xsl:value-of select="."/>, &#160; </xsl:for-each> </p> </xsl:for-each>

试试这个......

size

这会获取<productsize><price>属性的值,并使用它来查找具有相同size属性的<price>元素

请参阅此XMLPlayground for a working demo


根据OP的评论,以下行匹配整个文档中的所有<xsl:for-each select="//price[@size=$sizevar]"> 个元素......

<productsize>

所以我将其更改为以下内容,它只会在父项中找到这些元素(即<price>元素<xsl:for-each select="../price[@size=$sizevar]"> 元素是其中的子项。)

{{1}}

答案 1 :(得分:2)

假设您的源有一个名称空间,它应该在xmlns元素或某个祖先中有一个product声明。我会假设这样的事情:

<product xmlns="your-namespace"> 
    <productsize measurement="ml">250</productsize>
    <productsize measurement="ml">500</productsize>
    ...
</product>

在这种情况下,您还必须在XSL中声明该命名空间:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:x="your-namespace" version="1.0"> ... </xsl:stylesheet>

然后,要获得所需的结果,可以使用此样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="your-namespace"  version="1.0">

    <xsl:output method="text"/>

    <xsl:template match="/">
        <xsl:apply-templates select="x:product/x:productsize"/>
    </xsl:template>

    <xsl:template match="x:productsize">
        <xsl:variable name="size" select="."></xsl:variable>
        <xsl:value-of select="."/>
        <xsl:value-of select="@measurement"/><xsl:text> </xsl:text>
        <xsl:apply-templates select="../x:price[@size=$size]"/><xsl:text>
</xsl:text>
    </xsl:template>

    <xsl:template match="x:price">
        <xsl:value-of select="@packsize"/><xsl:text>=£</xsl:text>
        <xsl:value-of select="."/>
        <xsl:if test="not(position() = last())">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

至于为什么你的样式表不起作用,有很多可能的原因。如果正确声明了名称空间,则您尝试在price的上下文中阅读productsize,但它们不是嵌套的。您必须使用相对或绝对XPath表达式访问移出上下文的每个价格。我上面使用了../price,但它也适用于//price

我假设你没有发布任何其他代码并且不能从你的例子中假设是不相关的。如果您有其他product元素或products实际上不是root,则必须调整样式表。