2015-02-06 2 views
0

Я новичок в XSL и сталкиваюсь с проблемами, чтобы группировать элементы xml с тем же именем. вот мой вклад XML-элементпроблемы с группировкой с дочерними узлами

<Products> 
<Product type='Item' id='111'> 
    <Group1> 
     <color>Blue</color> 
     <item>xxx</item> 
    </Group1> 
    <Group1> 
     <color>Green</color> 
      <item>yyy</item> 
    </Group1> 
    <Group2> 
     <color>Yellow</color> 
     <item>xxx</item> 
    </Group2> 
    <Group2> 
     <color>White</color> 
      <item>yyy</item> 
    </Group2> 
    <Product type='ChildItem'> 
     <Group1> 
      <color>Blue</color> 
      <item>xxx</item> 
     </Group1> 
     <Group1> 
      <color>Green</color> 
       <item>yyy</item> 
     </Group1> 
     <Group2> 
      <color>Yellow</color> 
      <item>xxx</item> 
     </Group2> 
     <Group2> 
      <color>White</color> 
       <item>yyy</item> 
     </Group2> 
    </Product> 
</Product> 
<Product type='Item' id='222'> 
    <Group1> 
     <color>Blue</color> 
     <item>xxx</item> 
    </Group1> 
    <Group1> 
     <color>Green</color> 
      <item>yyy</item> 
    </Group1> 
    <Group2> 
     <color>Yellow</color> 
     <item>xxx</item> 
    </Group2> 
    <Group2> 
     <color>White</color> 
      <item>yyy</item> 
    </Group2> 
    <Product type='ChildItem'> 
     <Group1> 
      <color>Blue</color> 
      <item>xxx</item> 
     </Group1> 
     <Group1> 
      <color>Green</color> 
       <item>yyy</item> 
     </Group1> 
     <Group2> 
      <color>Yellow</color> 
      <item>xxx</item> 
     </Group2> 
     <Group2> 
      <color>White</color> 
       <item>yyy</item> 
     </Group2> 
    </Product> 
</Products> 

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

<Products> 
<Product type='Item' id='111'> 
    <Group1> 
     <color>Blue</color> 
     <item>xxx</item> 
     <color>Green</color> 
      <item>yyy</item> 
    </Group1> 
    <Group2> 
     <color>Yellow</color> 
     <item>xxx</item> 
     <color>White</color> 
      <item>yyy</item> 
    </Group2> 
    <Product type='ChildItem'> 
     <Group1> 
      <color>Blue</color> 
      <item>xxx</item> 
      <color>Green</color> 
      <item>yyy</item> 
     </Group1> 
     <Group2> 
      <color>Yellow</color> 
      <item>xxx</item> 
      <color>White</color> 
      <item>yyy</item> 
     </Group2> 
    </Product> 
</Product> 
<Product type='Item' id='222'> 
    <Group1> 
     <color>Blue</color> 
     <item>xxx</item> 
     <color>Green</color> 
      <item>yyy</item> 
    </Group1> 
    <Group2> 
     <color>Yellow</color> 
     <item>xxx</item> 
     <color>White</color> 
      <item>yyy</item> 
    </Group2> 
    <Product type='ChildItem'> 
     <Group1> 
      <color>Blue</color> 
      <item>xxx</item> 
      <color>Green</color> 
      <item>yyy</item> 
     </Group1> 
     <Group2> 
      <color>Yellow</color> 
      <item>xxx</item> 
      <color>White</color> 
      <item>yyy</item> 
     </Group2> 
    </Product> 
</Product> 
</Products> 

Am используя ниже XSL-файла для преобразования, но не получают выход, как ожидается

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:key name="elements" match="/Product/*" use="name()"/> 
<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:for-each select="*[count(. | key('elements', name())[1]) = 1]"> 
      <xsl:copy> 
       <xsl:apply-templates select="key('elements', name())/*"/> 
      </xsl:copy> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

ответ

1

Вы группируете дочерние элементы Product по имени, но эту группу необходимо выполнять отдельно для каждого Продукта, и поэтому вам нужна ссылка на Product является использование ключа

<xsl:key name="elements" 
     match="Product/*[not(self::Product)]" 
     use="concat(name(), '|', generate-id(..))"/> 

Обратите внимание, как ключевой матч не имеет префикс /, в противном случае он будет соответствовать только корневой элемент, называемый Product, который не соответствовал бы ничего в вашем случае. Также отмечает, что он соответствует только элементам Product.

(а также не использование generate-id(), который генерирует уникальный идентификатор для Product элемента для его идентификации)

Далее вам необходимо изменить свой второй шаблон, чтобы соответствовать Product, не \*, потому что \* только собирается соответствует корневому элементу. Затем в этом шаблоне, вы получите сгруппированные элементы следующим образом:

<xsl:for-each 
    select="*[generate-id() = generate-id(key('elements', concat(name(), '|', generate-id(..)))[1])]"> 

Попробуйте этот XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:key name="elements" match="Product/*[not(self::Product)]" use="concat(name(), '|', generate-id(..))"/> 

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

<xsl:template match="Product"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <xsl:for-each select="*[generate-id() = generate-id(key('elements', concat(name(), '|', generate-id(..)))[1])]"> 
      <xsl:copy> 
       <xsl:apply-templates select="key('elements', concat(name(), '|', generate-id(..)))/*"/> 
      </xsl:copy> 
     </xsl:for-each> 
     <xsl:apply-templates select="Product" /> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 
+0

Спасибо большое ... он работал –

+0

@BhavyaV Пожалуйста, не забудьте [принять этот ответ] (http://stackoverflow.com/help/someone-answers), если он решил вашу проблему. Благодаря! –

+0

Хороший код группировки, +1. –

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