Перевести XML с помощью XSLT groupby - PullRequest
0 голосов
/ 26 февраля 2019

Я следую XML и пытаюсь перевести его с помощью XSLT в другой формат, который указан ниже.Что-то не так с кодом XSLT

<resultSet>
<Record>
<OrderID>50321523</OrderID>
<AttributeName>Color</AttributeName>
<AttributeValue>Matt-Light-Brown</AttributeValue>
</Record>
<Record>
<OrderID>50321523</OrderID>
<AttributeName>Size</AttributeName>
<AttributeValue>43.0-18</AttributeValue>
</Record>
<Record>
<OrderID>50321513</OrderID>
<AttributeName>Color</AttributeName>
<AttributeValue>Matt-Light-Brown</AttributeValue>
</Record>
<Record>
<OrderID>50321513</OrderID>
<AttributeName>Size</AttributeName>
<AttributeValue>43.0-18</AttributeValue>
</Record>
</resultSet>

Целевой XML:

<Record>
<Orders>
<OrderID>50321523</OrderID>
<Color>Matt-Light-Brown</Color>
<Size>43.0-18</Size>
</Orders>
<Orders>
<OrderID>50321513</OrderID>
<Color>Matt-Light-Brown</Color>
<Size>43.0-18</Size>
</Orders>
</Record>

Ниже приведен код XSLT, который я использую:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
<xsl:output indent="yes"/>    
  <xsl:key name="groups" match="/resultSet/Record" use="OrderID" />

  <xsl:template match="/Record">
    <xsl:apply-templates select="Record[generate-id() = generate-id(key('groups', OrderID)[1])]"/>
  </xsl:template>
  <xsl:template match="Record">
      <xsl:for-each select="key('groups', OrderID)">
<xsl:element name="{AttributeName}">
            <xsl:value-of select="AttributeValue"/>
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Но этоXSLT не работает должным образом.Может кто-нибудь помочь с этим?

1 Ответ

0 голосов
/ 26 февраля 2019

Как уже упоминалось в комментариях, ваш первый шаблон должен соответствовать resultSet.Выполнение /Record будет соответствовать любому, только если Record был корневым элементом, а это не так.

Кроме того, в вашем втором шаблоне отсутствует закрывающий </xsl:element>, хотя это может быть опечаткой.Но в любом случае вам все равно нужно добавить создание элемента Orders и скопировать существующий OrderID.

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

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="1.0">
  <xsl:output indent="yes"/>    

  <xsl:key name="groups" match="Record" use="OrderID" />

  <xsl:template match="/resultSet">
    <xsl:apply-templates select="Record[generate-id() = generate-id(key('groups', OrderID)[1])]"/>
  </xsl:template>

  <xsl:template match="Record">
    <Orders>
      <xsl:copy-of select="OrderID" />
      <xsl:for-each select="key('groups', OrderID)">
        <xsl:element name="{AttributeName}">
          <xsl:value-of select="AttributeValue"/>
        </xsl:element>
      </xsl:for-each>
    </Orders>
  </xsl:template>
</xsl:stylesheet>

Обратите внимание, что естьне нужно использовать полный путь к элементу в совпадении с xsl:key, если вы хотите сопоставить их все где угодно.

Обратите внимание, если вы можете использовать XSLT 2.0 (а это означает использование процессора, которыйподдерживает XSLT 2.0. Вы не можете просто изменить номер версии на 2.0 и ожидать, что он будет работать, если ваш процессор XSLT поддерживает только XSLT 1.0), вы могли бы написать это так:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
  <xsl:output indent="yes"/>    

  <xsl:template match="/resultSet">
    <xsl:for-each-group select="Record" group-by="OrderID">
      <Orders>
        <xsl:copy-of select="OrderID" />
        <xsl:for-each select="current-group()">
          <xsl:element name="{AttributeName}">
            <xsl:value-of select="AttributeValue"/>
          </xsl:element>
        </xsl:for-each>
      </Orders>
    </xsl:for-each-group>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...