2016-09-01 3 views
0

Я изо всех сил пытаюсь найти правильный подход к проблеме, с которой я столкнулся.
мне нужно обновить «цвет» узел «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> 

ответ

0

мне нужно обновить «цвет» узел «xml1» с атрибутом «colorDef» из элемента продукта в «xml2»

Если вы хотите обновить только color, почему бы не матч шаблона его непосредственно, а не его материнской компании citem:

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

Плохо, как всегда для простоты, представляю основной пример. Но на самом деле, я буду обновлять несколько элементов под citem, конечно, я могу повторить выше, но это будет неэффективно. – yuris

+0

"* Я буду обновлять несколько элементов под citem, *« Итак? Сделайте шаблоны для них тоже. Или, если хотите, создайте шаблон для конкретного 'citem' (просто удалите часть'/color' из шаблона соответствия выше), а затем обработайте дочерние элементы оттуда. –

+0

есть проблема с этим, в случае, если нет соответствующего prodId в xml2, тогда элемент «color» с совпадением «FavType» удаляется! Почему это происходит? – yuris

Смежные вопросы