2016-06-29 4 views
0

Мой исходный XML выглядит следующим образом:XSLT: Группа различных типов элементов

<A> 
    <item> 
    <X>10</X> 
    <Y>20</Y> 
    <Data1>Foo</Data1> 
    </item> 
</A> 
<B> 
    <item> 
    <X>10</X> 
    <Y>20</Y> 
    <Data2>Bar</Data2> 
    </item> 
</B> 
<A> 
    <item> 
    <X>11</X> 
    <Y>20</Y> 
    <Data1>Foo2</Data1> 
    </item> 
</A> 
<B> 
    <item> 
    <X>11</X> 
    <Y>20</Y> 
    <Data2>Bar2</Data2> 
    </item> 
</B> 

Обратите внимание, что A s и s B всегда происходят попарно по отношению к значениям X и Y. Также обратите внимание, что есть и другие элементы, содержащие вложенный элемент item, который следует игнорировать. Теперь моя цель состоит в том, чтобы сгруппировать элементы, имеющие одинаковые значения для X и Y в новые элементы, похожие на это:

<NewElement> 
    <X>10</X> 
    <Y>20</Y> 
    <Data1>Foo</Data1> 
    <Data2>Bar</Data2> 
</NewElement> 
<NewElement> 
    <X>11</X> 
    <Y>20</Y> 
    <Data1>Foo2</Data1> 
    <Data2>Bar2</Data2> 
</NewElement> 

Я прочитал о Muenchian группировки, но мне кажется, что это работает только для одних и тех же элементов (например, в моем примере я мог бы группировать все A с теми же значениями для X и Y). Как я могу группировать разные элементы?

+1

Если я правильно понял ваше описание правильно, это на самом деле не о группировка. Кажется, вам нужно создать 'NewElement' для каждого' A' и заполнить его данными как из текущего 'A', так и из соответствующего' B'. –

+0

Я думаю, вы правы - глупый я. Я отправлю свое решение (что, вероятно, немного легче понять), и согласитесь, что один - надеюсь, что вы довольны тем, что «ответ - полезный» кредит ... – csoltenborn

ответ

0

Майкл был прав - не нужно выполнять группировку для моей проблемы. Вот решение, которое я закончил с использованием, что, вероятно, не так элегантно, как один, публикуемые им, но, возможно, немного легче понять: (?)

<xsl:template match="A/item"> 
    <NewElement> 
    <X><xsl:value-of select="X"/></X> 
    <Y><xsl:value-of select="Y"/></Y> 
    <Data1><xsl:value-of select="Data1"/></Data1> 
    <Data2> 
     <xsl:variable name="localX" select="X"/> 
     <xsl:variable name="localY" select="Y"/> 
     <xsl:value-of select="../../B/item[X = $localX and Y = $localY]/Data2"/> 
    </Data2> 
    </NewElement> 
</xsl:template> 
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="b" match="B/item" use="concat(X, '|', Y)" /> 

<xsl:template match="/root"> 
    <root> 
     <xsl:for-each select="A/item"> 
      <NewElement> 
       <xsl:copy-of select="*"/> 
       <xsl:copy-of select="key('b', concat(X, '|', Y))/Data2"/> 
      </NewElement> 
     </xsl:for-each> 
    </root> 
</xsl:template> 

</xsl:stylesheet> 

применены к входному примеру (! После добавления root элемент, чтобы сделать его хорошо сформированные), производит:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <NewElement> 
     <X>10</X> 
     <Y>20</Y> 
     <Data1>Foo</Data1> 
     <Data2>Bar</Data2> 
    </NewElement> 
    <NewElement> 
     <X>11</X> 
     <Y>20</Y> 
     <Data1>Foo2</Data1> 
     <Data2>Bar2</Data2> 
    </NewElement> 
</root>