Xslt преобразование - PullRequest
       5

Xslt преобразование

2 голосов
/ 07 июля 2011

Я собираюсь преобразовать первый XML во второй, используя преобразование XSLT

Первый:

<Data> 
 <Time> 
  <ID>IDvalue1</ID> 
  <field1>PropertyValue1</field1> 
  <field2>PropertyName1</field2> 
 </Time> 
 <Time>
  <ID>IDvalue2</ID> 
  <field1>PropertyValue2</field1> 
  <field2>PropertyName1</field2> 
 </Time>
 <Time> 
  <ID>IDvalue1</ID> 
  <field1>PropertyValue3</field1> 
  <field2> PropertyName2</field2> 
 </Time> 
 <Time> 
  <ID>IDvalue2</ID> 
  <field1>PropertyValue4</field1> 
  <field2>PropertyName2</field2> 
 </Time>
</Data>
....

Второй:

<Data> 
 <Time> 
  <ID>IDvalue1</ID> 
  <PropertyName1>PropertyValue1</PropertyName1> 
  <PropertyName2>PropertyValue3</PropertyName2> 
 </Time> 
 <Time> 
  <ID>IDvalue2</ID> 
  <PropertyName1>PropertyValue2</ PropertyName1> 
  <PropertyName2>PropertyValue4</PropertyName2> 
 </Time> 
</Data>
.....

В первомXML есть количество узлов ID, которые имеют одинаковые значения.Во втором XML они скомпилированы в единые узлы.После каждого идентификатора в первом XML есть узлы field1 и field2.Во втором XML должны быть созданы новые узлы, где field2 - это имя тега, а field1 - это значение.Эти новые узлы собраны из всех ID-узлов с одинаковым значением.

Не могли бы вы помочь мне написать XSLT-код?

Ответы [ 3 ]

2 голосов
/ 07 июля 2011

Это стандартный вопрос группировки. Вы найдете массу помощи, если будете искать «Группировка XSLT». Группировать в XSLT 2.0 очень легко, используя инструкцию xsl: for-each-group, но довольно сложно в XSLT 1.0, как продемонстрировал Полищук. (Лично я даже не пытаюсь отвечать на вопросы о группировке, не зная, какую версию XSLT вы используете и почему - код в этих двух случаях такой разный).

2 голосов
/ 07 июля 2011

Используйте этот шаблон:

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

  <xsl:key name="k" match="Time" use="ID"/>

  <xsl:template match="Data">
    <Data>
      <xsl:apply-templates select="Time[generate-id(.) = generate-id(key('k', ID))]"/>
    </Data>
  </xsl:template>

  <xsl:template match="Time">
    <Time>
      <xsl:copy-of select="ID"/>
      <xsl:for-each select="key('k', ID)">
        <xsl:element name="{normalize-space(field2)}">
          <xsl:value-of select="field1"/>
        </xsl:element>
      </xsl:for-each> 
    </Time>
  </xsl:template>

</xsl:stylesheet>

Выход:

<?xml version="1.0" encoding="utf-8"?>
<Data>
  <Time>
    <ID>IDvalue1</ID>
    <PropertyName1>PropertyValue1</PropertyName1>
    <PropertyName2>PropertyValue3</PropertyName2>
  </Time>
  <Time>
    <ID>IDvalue2</ID>
    <PropertyName1>PropertyValue2</PropertyName1>
    <PropertyName2>PropertyValue4</PropertyName2>
  </Time>
</Data>
1 голос
/ 08 июля 2011

Microsoft .NET Framework пока не поддерживает XSLT 2.0. НО, если вы собираетесь использовать XSLT из ASP .NET, вы можете легко реализовать (@Michael Key) Saxon. См. эту тему для получения дополнительной информации.

Когда вы будете готовы, ваше решение для группировки будет очень простым. Вот пример группировки XSLT 2.0, примененный к вашему вопросу:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>

    <xsl:template match="Data">
        <Data>
            <xsl:for-each-group select="Time" group-by="ID">
                <Time>
                    <xsl:copy-of select="ID"/>
                    <xsl:apply-templates select="current-group()"/>
                </Time>
            </xsl:for-each-group>
        </Data>
    </xsl:template>

    <xsl:template match="Time">
        <xsl:element name="{field2}">
            <xsl:value-of select="field1"/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...