На основе объекта соответствующие значения должны быть приняты с использованием xslt

#xslt-1.0

#xslt-1.0

Вопрос:

ВХОДНОЙ XML

     <root>
       <file1>
          <commodity>
              <units>1</units>
              <obj>mango</obj>
          </commodity>
          <commodity>
              <units>5</units>
              <obj>guava</obj>
           </commodity>
       </file1>

       <file2>
          <category>
              <object>guava</object>
              <type>CAT1</type>
              <colour>green</colour>
          </category>
          <category>
              <object>mango</object>
              <type>CAT2</type>
              <colour>yellow</colour>
          </category>
       </file2>
   </root>
  

Мне нужно сравнить значения obj в file1 и object в file2 под root, если же мне нужно взять их соответствующие единицы измерения, тип и цвет и создать следующий вывод с использованием xslt.

ВЫВОД XML

     <output>
        <com>
            <name>guava</name>
            <num>5</num>
            <category>CAT1</category>
            <col>green</col>
        </com>
        <com>
            <name>mango</name>
            <num>1</num>
            <category>CAT2</category>
            <col>yellow</col>
        </com>
     </output>
  

Я попробовал приведенный ниже XSLT, но ответ не соответствует ожиданиям. Он не зацикливается должным образом. Не могли бы вы сказать мне, где я ошибаюсь.

   <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   version="1.0">
  <xsl:output method="xml" version="1.0" encoding="UTF-8"
    indent="yes" />
  <xsl:key name="object-search" match="root/file1/commodity" use="obj" />
  <xsl:template match="/">
    <output>
        <xsl:for-each select="key('object-search', //category/object)">
            <com>

                <name>
                    <xsl:value-of select="obj" />
                </name>
                <num>
                    <xsl:value-of select="units" />
                </num>
                <category>
                    <xsl:value-of
                        select="//root/file2/category/type" />
                </category>
                <col>
                    <xsl:value-of
                        select="//root/file2/category/colour" />
                </col>

            </com>
        </xsl:for-each>
    </output>
  </xsl:template>
  </xsl:stylesheet>
  

Ответ №1:

Попробуйте сделать это так:

XSLT 1.0

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

<xsl:key name="cat" match="category" use="object" />

<xsl:template match="/root">
    <output>
        <xsl:for-each select="file1/commodity">
            <com>
                <name>
                    <xsl:value-of select="obj" />
                </name>
                <num>
                    <xsl:value-of select="units" />
                </num>
                <xsl:variable name="cat" select="key('cat', obj)" />
                <category>
                    <xsl:value-of select="$cat/type" />
                </category>
                <col>
                    <xsl:value-of select="$cat/colour" />
                </col>
            </com>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>
  

Обратите внимание, что результат немного отличается от того, что вы опубликовали:

 <?xml version="1.0" encoding="UTF-8"?>
<output>
   <com>
      <name>mango</name>
      <num>1</num>
      <category>CAT2</category>
      <col>yellow</col>
   </com>
   <com>
      <name>guava</name>
      <num>5</num>
      <category>CAT1</category>
      <col>green</col>
   </com>
</output>
  

В качестве альтернативы, вы могли бы сделать:

XSLT 1.0

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

<xsl:key name="com" match="commodity" use="obj" />

<xsl:template match="/root">
    <output>
        <xsl:for-each select="file2/category">
            <xsl:variable name="com" select="key('com', object)" />
            <com>
                <name>
                    <xsl:value-of select="$com/obj" />
                </name>
                <num>
                    <xsl:value-of select="$com/units" />
                </num>
                <category>
                    <xsl:value-of select="type" />
                </category>
                <col>
                    <xsl:value-of select="colour" />
                </col>
            </com>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>
  

и получаем:

 <?xml version="1.0" encoding="UTF-8"?>
<output>
   <com>
      <name>guava</name>
      <num>5</num>
      <category>CAT1</category>
      <col>green</col>
   </com>
   <com>
      <name>mango</name>
      <num>1</num>
      <category>CAT2</category>
      <col>yellow</col>
   </com>
</output>