Реструктуризация XML с использованием XSLT 2.0 - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь реструктурировать XML. Поэтому нужно разделить продукт. Я сделал пару xslt с помощью вас самих, однако это было для разделения XML на несколько XML. Это, однако, кажется немного более сложным. Я борюсь с тем, с чего начать. Любая помощь будет отличной. Я использую XSLT 2.0.

Приветствия

Входной XML

<?xml version="1.0"?>
<Order_Root>
  <Orders Number="12345">
    <Info Name="John Doe" Reference="1/2/2019">
      <LineItems>
        <LineItem LineItemNumber="01" CustomerProductName="Test">
          <LineItemPrice Price="0" Charge="0" />
          <Products>
            <Product ProductName="A" />
            <Product ProductName="B" />
            <Product ProductName="C" />
          </Products>
        </LineItem>
      </LineItems>
    </Info>
  </Orders>
</Order_Root>

Результат XML

<?xml version="1.0"?>
<Order_Root>
  <Orders Number="12345">
    <Info Name="John Doe" Reference="1/2/2019">
      <LineItems>
        <LineItem LineItemNumber="01" CustomerProductName="Test">
          <LineItemPrice Price="0" Charge="0" />
          <Products>
            <Product ProductName="A" />
          </Products>
        </LineItem>
        <LineItem LineItemNumber="01" CustomerProductName="Test">
          <LineItemPrice Price="0" Charge="0" />
          <Products>
            <Product ProductName="B" />
          </Products>
        </LineItem>
        <LineItem LineItemNumber="01" CustomerProductName="Test">
          <LineItemPrice Price="0" Charge="0" />
          <Products>
            <Product ProductName="C" />
          </Products>
        </LineItem>
      </LineItems>
    </Info>
  </Orders>
</Order_Root>

1 Ответ

0 голосов
/ 11 января 2019

Я думаю, что это может быть хорошим примером использования функции snapshot XSLT 3 вместе со вторым режимом и параметром туннеля для передачи этого LineItemPrice:

<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:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

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

    <xsl:template match="LineItem">
        <xsl:apply-templates select=".//Product!snapshot()/ancestor::LineItem" mode="price">
            <xsl:with-param name="price" tunnel="yes" select="LineItemPrice"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="LineItem" mode="price">
        <xsl:param name="price" tunnel="yes"/>
        <xsl:copy>
            <xsl:apply-templates select="@*, $price, node()" mode="#current"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / bFN1y8J

XSLT 3 доступен с Saxon 9.8 или более поздней версии или Altova 2017 и более поздней версии, поэтому есть вероятность, что если вы используете современный процессор XSLT 2, у вас есть процессор, который также может использовать XSLT 3 вместо тегов XSLT 2.

XSLT 2 не имеет snapshot, но, конечно, вы можете попытаться реализовать один и тот же подход, заключающийся в том, чтобы продвигать каждый продукт в отдельном режиме, чтобы также реконструировать поддерево, только теперь другие шаблоны должны исключать все, кроме один Product:

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

    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="LineItem">
        <xsl:apply-templates select=".//Product"/>
    </xsl:template>

    <xsl:template match="Product">
        <xsl:apply-templates select="ancestor::LineItem" mode="price">
            <xsl:with-param name="product" tunnel="yes" select="."/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="Product" mode="price">
        <xsl:param name="product" tunnel="yes"/>
        <xsl:if test=". is $product">
            <xsl:next-match/>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / bFN1y8J / 1

...