Я изо всех сил пытаюсь найти правильный подход к проблеме, с которой я столкнулся.
мне нужно обновить «цвет» узел «xml1» с атрибутом «colorDef» элемента продукта в «xml2»Вложенные для каждого для двойного соответствия
согласование «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>
код, который в настоящее время решает первую 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>
Какое предпочтительное решение? Вложенные для каждого?
Update: Новый 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>
в случае PRODID в xml1 не существует в xml2, я получаю это:
<citem>
<type>XX2</type>
<color/>
</citem>
вместо оригинала
<citem>
<type>XX2</type>
<color>Blue</color>
</citem>
Плохо, как всегда для простоты, представляю основной пример. Но на самом деле, я буду обновлять несколько элементов под citem, конечно, я могу повторить выше, но это будет неэффективно. – yuris
"* Я буду обновлять несколько элементов под citem, *« Итак? Сделайте шаблоны для них тоже. Или, если хотите, создайте шаблон для конкретного 'citem' (просто удалите часть'/color' из шаблона соответствия выше), а затем обработайте дочерние элементы оттуда. –
есть проблема с этим, в случае, если нет соответствующего prodId в xml2, тогда элемент «color» с совпадением «FavType» удаляется! Почему это происходит? – yuris