在节点上拆分XML并插入常规信息

在节点上拆分XML并插入常规信息,xml,xslt-2.0,Xml,Xslt 2.0,客户可以提供具有以下结构的整合XML: <invoices> <invoice> <order_id> <ordernumber>1000</ordernumber> </order_id> <general_info/> <address/> <product> <id>A</id>

客户可以提供具有以下结构的整合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>

1000
A.
B
C
2000
D
根元素“invoices”可以包含“invoices”的多个实例(订单本身,在本例中为2个订单) 但是,“发票”也可以包含“产品”的多个实例(订单行、订单id 1000的3个订单行和订单id 2000的1个订单行)

我们需要的是每个订单行包含一个XML,其中包含一个“产品”和“发票”,订单id、一般信息和地址始终存在

<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>

1000
A.
1000
B
1000
C
2000
D
我们一直在考虑这样一种多重拆分方案: 1.在发票上拆分以获得单独的订单 2.将单独的订单拆分为订单行,并转换(XSL)单独的XML以包括订单id、常规信息和地址

拆分1(在“发票”上)实现无问题(尽管是在外部程序的帮助下)

我们不能很好地工作不能很好地工作是分割和保留一般信息。 到目前为止,我们已经尝试使用模板匹配和for each语句对XML进行转换,但无法使其正常工作


如果有人知道如何做到这一点?

似乎是直截了当的

  <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>


在线

谢谢Martin,这确实适用于XML示例。 刚才注意到,在生产XML中,节点“product”实际上要低一级(父节点“products”)


1000
一般A
地址A
A.
B
C
2000
将军B
地址B
D
我已经调整了apply模板以反映这一点,但在使XSLT的后一部分正常工作方面存在问题(template match=“product”)

XSLT


输出包含“项目”数据,但缺少“订单id”、“一般信息”和“地址”。
我认为这是因为“产品”的级别与“./xxxxxx”不匹配?

请不要将更改后的要求作为答案发布,而是使用新的代码示例编辑您的问题。至于级别,您当然需要查找两个级别,例如
。/../general\u info
,而不是
。/general\u info
。或者选择
祖先::发票/general\u info
。很抱歉,在以后的帖子中,我将更新原始问题。我已经相应地调整了XSLT,现在可以使用了。还有一个问题。在生产XML中,发票号是一个实体而不是一个节点,例如。如何将其复制到节点“invoicenumber”?
<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>
<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>