【发布时间】:2016-09-01 19:39:19
【问题描述】:
我正在努力为我所面临的问题找到正确的方法。
我需要更新'xml1'的'color'节点,使用'xml2'中产品元素的属性'colorDef'
'xml1'和'xml2'通过两个xml中存在的'prodId'属性匹配(选项:多对多),但还有额外的要求:
我只需要更新特定的 '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>
目前解决第一个要求的代码:
<?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>
【问题讨论】: