基于后代值的XSL转换?

时间:2010-02-25 18:46:54

标签: xml xslt

我们有一些软件可以接收我们翻译的XML数据Feed,以匹配我们的Feed解析器。我正在努力引入一个新的feed,由于源代码的来源,我很难分出其中一个类别。我不能改变我们的XML格式或者他们的格式,所以我坚持不懈只有XSL(T)才能做到这一点。

在这个理论示例中,我有一个产品列表,这些产品将显示在生成的几个目录中。我们对100%加价的产品的处理方式与80%加价的产品不同。通常我们将较高标记的项目作为单独的产品获得,但在这种情况下,它在节点树中嵌入得更低。

我们得到的XML看起来像这样:

<?xml version="1.0" encoding="utf-8" ?> 
<products>
    <product>
        <name>lawnmower</name>
        <prices>
            <price>
                <supplier>amazon</supplier>
                <markup>100%</markup>
                <price>$200</price>
            </price>
            <price>
                <supplier>newegg</supplier>
                <markup>80%</markup>
                <price>$160</price>
            </price>
            <price>
                <supplier>home depot</supplier>
                <markup>80%</markup>
                <price>$150</price>
            </price>
        </prices>
    </product>
    <product>
        <name>laptop</name>
        <prices>
            <price>
                <supplier>newegg</supplier>
                <markup>80%</markup>
                <price>$1000</price>
            </price>
        </prices>
    </product>
    <product>
        <name>my little pony</name>
        <prices>
            <price>
                <supplier>amazon</supplier>
                <markup>80%</markup>
                <price>$50</price>
            </price>
            <price>
                <supplier>newegg</supplier>
                <markup>80%</markup>
                <price>$40</price>
            </price>
        </prices>
    </product>
</products>

我们希望将其转换为如下所示:

<?xml version="1.0" encoding="utf-8" ?> 
<prodlist>
    <products>
        <product category="lawnmower">
            <price supplier="newegg">$160</price>
            <price supplier="home depot">$150</price>
        </product>
        <product category="lawnmower100">
            <price supplier="amazon">$200</price>
        </product>
        <product category="laptop">
            <price supplier="newegg">$1000</price>
        </product>
        <product category="my little pony">
            <price supplier="amazon">$50</price>
        </product>
    </products>
</prodlist>

我正在使用一些看起来大致相似的XSL(我已经剪掉了所有周围的XSL以便尝试一点点简洁):

<xsl:template match="products">
    <xsl:element name="product">
        <xsl:choose>
            <xsl:when test = "name = 'lawnmower' and prices/price/markup = '100%'">
                <xsl:attribute name="category">lawnmower100</xsl:attribute>
                <xsl:apply-templates select="prices" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:attribute name="category">
                    <xsl:value-of select="name" />
                </xsl:attribute>
                <xsl:apply-templates select="prices" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:element>
</xsl:template>

使用它会给我一些不好的结果;割草机的一切都被拉入“割草机100”类别,给我一个看起来像这样的结果:

<?xml version="1.0" encoding="utf-8" ?> 
<prodlist>
    <products>
        <product category="lawnmower100">
            <price supplier="amazon">$200</price>
            <price supplier="newegg">$160</price>
            <price supplier="home depot">$150</price>
        </product>
        <product category="laptop">
            <price supplier="newegg">$1000</price>
        </product>
        <product category="my little pony">
            <price supplier="amazon">$50</price>
        </product>
    </products>
</prodlist>

我不太确定如何选择100%标记的项目,但无论我现在做什么都不行。我玩过,但我认为我没有正确使用它们,因为我一直在结束这个结果。

我希望我已经提供了足够的细节,这是有道理的!

1 个答案:

答案 0 :(得分:2)

除非我非常错误,否则应该是这样的:

<xsl:template match="products">
  <xsl:apply-templates select="product[prices/price/markup='100%']" mode="hundred"/>
  <xsl:apply-templates select="product[prices/price/markup='80%']" mode="eighty"/>
</xsl:template>

<xsl:template match="product" mode="hundred">
  <xsl:element name="product">
    <xsl:attribute name="category"><xsl:value-of select="name" /></xsl:attribute>
    <xsl:apply-templates select="prices/price[markup='100%']"/>
  </xsl:element>
</xsl:template>

<xsl:template match="product" mode="eighty">
  <xsl:element name="product">
    <xsl:attribute name="category"><xsl:value-of select="concat(name,'80')" /></xsl:attribute>
    <xsl:apply-templates select="prices/price[markup='80%']"/>
  </xsl:element>
</xsl:template>

<xsl:template match="price">
  <!-- individual price processing here -->
</xsl:template>