嵌套for-each用于双重匹配

时间:2016-09-01 19:39:19

标签: xml xslt xslt-1.0

我正在努力为我所面临的问题找到正确的方法 我需要更新'xml1'的'color'节点,'xml2'中产品元素的属性'colorDef'

'xml1'和'xml2'的匹配通过'prodId'属性存在于两个xmls中(选项:多对多),但还有其他要求:

我只需要更新特定的'citem'(不是全部),需要更新'citem'元素,其中子元素'type'等于'FavType'元素。

XML1:

<?xml version="1.0" encoding="utf-8"?>
<Products>
    <Product prodId="390">
        <FavType>XX2</FavType>
        <citem>
            <type>XX1</type>
            <color>Green</color>
        </citem>
        <citem>
            <type>XX2</type>
            <color>Blue</color>
        </citem>
        <citem>
            <type>XX3</type>
            <color>Red</color>
        </citem>
    </Product>
</Products>

XML2:

<?xml version="1.0" encoding="utf-8"?>
<OrderCatalog>
    <Product prodId="390">
        <Item colorDef='Yellow'>Tusk</Item>     
    </Product>
    <Product prodId="500">      
        <Item colorDef='Yellow'>Dowel</Item>        
    </Product>
</OrderCatalog>

需要输出:

<?xml version="1.0" encoding="utf-8"?>
<Products>
    <Product prodId="390">
        <FavType>XX2</FavType>
        <citem>
            <type>XX1</type>
            <color>Green</color>
        </citem>
        <citem>
            <type>XX2</type>
            <color>Yellow</color>
        </citem>
        <citem>
            <type>XX3</type>
            <color>Red</color>
        </citem>
    </Product>
</Products>

Code,目前解决了第一个requirmnet:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="xml" indent="yes"/>


    <xsl:param name="f1" select="'xml20.xml'"/>
    <xsl:variable name="doc1" select="document($f1)"/>

    <xsl:key name="k1" match="OrderCatalog/Product" use="@prodId"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Products/Product/citem" >
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:variable name="prodId" select="../@prodId"/>
            <xsl:for-each select="$doc1">
                <color>
                    <xsl:value-of select="key('k1', $prodId)/Item/@colorDef"/>
                </color>
            </xsl:for-each>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

首选解决方案是什么? 嵌套为每个?

更新 来自答案的新XSL:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="xml" indent="yes"/>


    <xsl:param name="f1" select="'x20.xml'"/>
    <xsl:variable name="doc1" select="document($f1)"/>

    <xsl:key name="k1" match="OrderCatalog/Product" use="@prodId"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

   <xsl:template match="Products/Product/citem[type=../FavType]/color" >
    <xsl:copy>

        <xsl:variable name="prodId" select="../../@prodId"/>
        <xsl:for-each select="$doc1">
            <xsl:value-of select="key('k1', $prodId)/Item/@colorDef"/>
        </xsl:for-each>

    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

如果xml1中的prodid在xml2中不存在,我得到了这个:

 <citem>
     <type>XX2</type>
     <color/>
  </citem>

而不是原始

  <citem>
            <type>XX2</type>
            <color>Blue</color>
  </citem>

1 个答案:

答案 0 :(得分:0)

  

我需要更新'xml1'的'color'节点,属性'colorDef'为   'xml2'中的product元素

如果您只想更新print unpack("f", pack("f",12.2)); # "12.1999998092651" print unpack("d", pack("d",12.2)); # "12.2" printf "%.20f",unpack("f", pack("f",12.2)); # "12.19999980926513671875" printf "%.20f",unpack("d", pack("d",12.2)); # "12.19999999999999928946" ,为什么不让模板直接与其父color匹配:

citem