开发者

XSL transformation based on descendant values?

开发者 https://www.devze.com 2022-12-21 11:57 出处:网络
We have some software where we recieve XML data feeds that we translate to match our feed parser. I\'m working on bringing in a new feed and I\'m having a tough time splitting out one of the categorie

We have some software where we recieve XML data feeds that we translate to match our feed parser. I'm working on bringing in a new feed and I'm having a tough time splitting out one of the categories due to how the source feed comes in. I can't change our XML format or theirs, so I'm stuck with having to do this in nothing but XSL(T).

In this theoretical example, I have a list of products that will be displayed in a few catalogs that get generated. We treat products with 100% markup differently than items with 80% markup. Ordinarily we get the higher marked up items as a separate product, but in this case it's embedded much lower in the node tree.

The XML we get looks something like this:

<?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>

And we want to convert it to look like this:

<?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>
</pr开发者_运维技巧odlist>

I'm using some XSL that looks roughly like this (I've clipped out all of the surrounding XSL in order to attempt a little bit of brevity):

<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>

Using that is giving me some bad results though; everything for lawnmowers is getting pulled into the "lawnmower100" category, giving me a result that looks like this:

<?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>

I'm not too sure how I should be selecting out the 100% marked up items, but whatever I'm doing now isn't working. I've played with and but I don't think I'm using them correctly, since I keep ending up with this result.

I hope I've provided enough detail that this makes sense!


Unless I'm very much mistaken, that should be something like:

<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>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号