XSLT дублирует родительский элемент для каждого вхождения дочернего узла, но только с его следующими братьями и сестрами - PullRequest
0 голосов
/ 24 октября 2018

Мой входной XML -

<DataArea>
  <ReceiveDelivery>
      <ReceiveDeliveryHeader>
          .....
      </ReceiveDeliveryHeader>
      <ReceiveDeliveryItem>
            ....
      </ReceiveDeliveryItem>
      <ReceiveDeliveryItem>
            ....
      </ReceiveDeliveryItem>
      <ReceiveDeliveryHeader>
          .....
      </ReceiveDeliveryHeader>
      <ReceiveDeliveryItem>
            ....
      </ReceiveDeliveryItem>
 </ReceiveDelivery>
</DataArea>

И желаемый вывод -

<DataArea>
      <ReceiveDelivery>
          <ReceiveDeliveryHeader>
              .....
          </ReceiveDeliveryHeader>
          <ReceiveDeliveryItem>
                ....
          </ReceiveDeliveryItem>
          <ReceiveDeliveryItem>
                ....
          </ReceiveDeliveryItem>
       </ReceiveDelivery>
       <ReceiveDelivery>
          <ReceiveDeliveryHeader>
              .....
          </ReceiveDeliveryHeader>
          <ReceiveDeliveryItem>
                ....
          </ReceiveDeliveryItem>
       </ReceiveDelivery>
     </DataArea>

Может быть 1 или более элементов, следующих за заголовком.Я хочу, чтобы родительский узел ReceiveDelivery дублировался для каждого заголовка и элементов, которые следуют только за этим заголовком.Пожалуйста, помогите.

Спасибо Мартину за ваш вклад.
Я использую XSLT 2.0.Вот мой код

<xsl:stylesheet version="2.0" xmlns="http://schema.infor.com/InforOAGIS/2" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xs="http://www.w3.org/2001/XMLSchema" >

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

    <xsl:template match="ReceiveDelivery">
    <xsl:for-each-group select="*" group-starting-with="ReceiveDeliveryHeader">
      <ReceiveDelivery>         
              <xsl:copy-of select="current-group()"/>           
         </ReceiveDelivery>    
      </xsl:for-each-group> 
    </xsl:template> 
</xsl:stylesheet>   

Это так и должно быть?Но вывод такой же, как ввод.Не могли бы вы помочь?

1 Ответ

0 голосов
/ 24 октября 2018

В XSLT 2 или 3 это простая проблема группировки с использованием for-each-group group-starting-with:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="ReceiveDelivery">
      <xsl:for-each-group select="*" group-starting-with="ReceiveDeliveryHeader">
          <xsl:copy select="..">
              <xsl:copy-of select="current-group()"/>
          </xsl:copy>
      </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / 94hvTA2

ОбразецXSLT 3, но группировка работает аналогично XSLT 2, только вам нужно указать xsl:mode в качестве шаблона преобразования идентификаторов и использовать явный буквенный элемент результата <ReceiveDelivery> или <xsl:element name="{name(..)}"> вместо <xsl:copy select="..">.

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