Разделить XML на узел и вставить общую информацию - PullRequest
0 голосов
/ 04 июня 2018

Клиент может предоставить консолидированный XML со следующей структурой:

<invoices>
<invoice>
    <order_id>
        <ordernumber>1000</ordernumber>
    </order_id>
    <general_info/>
    <address/>
    <product>
        <id>A</id>
        <item/>
        <item/>
    </product>
    <product>
        <id>B</id>
        <item/>
        <item/>
    </product>
    <product>
        <id>C</id>
        <item/>
        <item/>
    </product>
</invoice>
<invoice>
    <order_id>
        <ordernumber>2000</ordernumber>
    </order_id>
    <general_info/>
    <address/>
    <product>
        <id>D</id>
        <item/>
        <item/>
    </product>
</invoice>
</invoices>

Корневой элемент "счета-фактуры" может содержать несколько экземпляров "счета-фактуры" (сам заказ, в данном случае 2 заказа). Однако«invoice» также может содержать несколько экземпляров «product» (строки заказа, 3 строки заказа для order_id 1000 и 1 для order_id 2000)

Нам нужен XML для каждой строки заказа, содержащей один «product» и «Счет-фактура "с указанием идентификатора заказа, общей информации и адреса всегда.

<invoices>
<invoice>
    <order_id>
        <ordernumber>1000</ordernumber>
    </order_id>
    <product>
        <general_info/>
        <address/>
        <id>A</id>
        <item/>
        <item/>
    </product>
</invoice>
<invoice>
    <order_id>
        <ordernumber>1000</ordernumber>
    </order_id>
    <product>
        <general_info/>
        <address/>
        <id>B</id>
        <item/>
        <item/>
    </product>
</invoice>
<invoice>
    <order_id>
        <ordernumber>1000</ordernumber>
    </order_id>
    <product>
        <general_info/>
        <address/>
        <id>C</id>
        <item/>
        <item/>
    </product>
</invoice>
<invoice>
    <order_id>
        <ordernumber>2000</ordernumber>
    </order_id>
    <general_info/>
    <address/>
    <product>
        <id>D</id>
        <item/>
        <item/>
    </product>
</invoice>
</invoices>

Мы рассматривали сценарий множественного разделения, подобный следующему: 1. Разделить накладную, чтобы получить отдельные заказы. 2. Разделить отдельные заказы на строки заказов и преобразовать (XSL) отдельные XML, чтобы включитьorder_id, общая информация и адрес.

Разделение 1 (по «счету») выполняется без проблем (хотя и с помощью внешней программы).

К чему мы не можем полностью добратьсяработа не может работать, это разделение и сохранение общей информации.Софар, мы пытались трансформировать XML, используя совпадения шаблонов и операторы for-each, но не можем заставить его работать должным образом.

Если у кого-то есть идея, как это сделать?

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Спасибо, Мартин, это действительно работает для примера XML.Просто заметил, что в производственном XML узел "продукт" на самом деле на один уровень ниже (родительский узел "продукты").

<invoices>
<invoice>
    <order_id>
        <ordernumber>1000</ordernumber>
    </order_id>
    <general_info>General A</general_info>
    <address>Adres A</address>
    <products>
        <product>
            <id>A</id>
            <item/>
            <item/>
        </product>
        <product>
            <id>B</id>
            <item/>
            <item/>
        </product>
        <product>
            <id>C</id>
            <item/>
            <item/>
        </product>
    </products>
</invoice>
<invoice>
    <order_id>
        <ordernumber>2000</ordernumber>
    </order_id>
    <general_info>General B</general_info>
    <address>Adres B</address>
    <products>
        <product>
            <id>D</id>
            <item/>
            <item/>
        </product>
    </products>
</invoice>
</invoices>

Я настроил шаблоны применения, чтобы отразить это, но есть проблемы, которые нужно получитьпоследняя часть XSLT работает (шаблон соответствует = "product")

XSLT

<xsl:template match="invoices">
    <xsl:copy>
        <xsl:apply-templates select="invoice/products/product"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="product">
    <invoice>
        <xsl:copy-of select="../order_id"/>
        <xsl:copy>
            <xsl:copy-of select="../general_info, ../address, *"/>
        </xsl:copy>
    </invoice>
</xsl:template>
</xsl:stylesheet>

Вывод содержит данные "item", но "order_id", "general_info" и "адрес "отсутствует.Я предполагаю, что это из-за уровня, на котором находится «продукт», и это больше не соответствует «../xxxxxx»?

0 голосов
/ 04 июня 2018

Кажется прямым с

  <xsl:template match="invoices">
    <xsl:copy>
        <xsl:apply-templates select="invoice/product"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="product">
      <invoice>
          <xsl:copy-of select="../order_id"/>
          <xsl:copy>
              <xsl:copy-of select="../general-info, ../address, *"/>
          </xsl:copy>
      </invoice>
  </xsl:template>

полный образец

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

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

  <xsl:template match="invoices">
    <xsl:copy>
        <xsl:apply-templates select="invoice/product"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="product">
      <invoice>
          <xsl:copy-of select="../order_id"/>
          <xsl:copy>
              <xsl:copy-of select="../general-info, ../address, *"/>
          </xsl:copy>
      </invoice>
  </xsl:template>

</xsl:stylesheet>

онлайн на https://xsltfiddle.liberty -development.net / 3NzcBt3

...