Java 使用xslt将一个XML节点的元素移动到子节点

Java 使用xslt将一个XML节点的元素移动到子节点,java,xml,xslt,Java,Xml,Xslt,基本上,我需要使用xsl将OrderRelease和Order的内容移动到OrderLine级别 输入XML示例: <OrderRelease EnterpriseCode="BRD" ReleaseNo="1234ABC" DocumentType="0001" SellerOrganizationCode="BU1" ShipNode="US1"> <Order Or

基本上,我需要使用xsl将OrderRelease和Order的内容移动到OrderLine级别

输入XML示例:

<OrderRelease EnterpriseCode="BRD" ReleaseNo="1234ABC" DocumentType="0001" SellerOrganizationCode="BU1" ShipNode="US1">
    <Order OrderDate="2019-06-13T09:27:36-04:00" Action="CANCEL" OrderNo="1234ABC">
        <Extn ExtnWMSOrderNumber="123ADS"/>
    </Order>    
    <OrderLines>
        <OrderLine Action="CANCEL" PrimeLineNo="1" SubLineNo="1" OrderedQty="5">
            <Item ItemID="A" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
        <OrderLine Action="" PrimeLineNo="2" SubLineNo="1" OrderedQty="10">
            <Item ItemID="B" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
        <OrderLine Action="CANCEL" PrimeLineNo="3" SubLineNo="1" OrderedQty="0">
            <Item ItemID="C" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
    </OrderLines>
</OrderRelease>

XML后期翻译示例:

<OrderLines>
        <OrderLine Action="CANCEL" PrimeLineNo="1" SubLineNo="1" OrderedQty="5" OrderDate="2019-06-13T09:27:36-04:00" OrderNo="1234ABC" EnterpriseCode="BRD" ReleaseNo="1234ABC" DocumentType="0001" SellerOrganizationCode="BU1" ShipNode="US1" AggregatorOrderId=”12345 >
            <Item ItemID="A" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
        <OrderLine Action="" PrimeLineNo="1" SubLineNo="1" OrderedQty="10" OrderDate="2019-06-13T09:27:36-04:00" OrderNo="1234ABC" EnterpriseCode="BRD" ReleaseNo="1234ABC" DocumentType="0001" SellerOrganizationCode="BU1" ShipNode="US1" AggregatorOrderId=”12345>
            <Item ItemID="B" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
        <OrderLine Action="CANCEL" PrimeLineNo="1" SubLineNo="1" OrderedQty="0" OrderDate="2019-06-13T09:27:36-04:00" OrderNo="1234ABC" EnterpriseCode="BRD" ReleaseNo="1234ABC" DocumentType="0001" SellerOrganizationCode="BU1" ShipNode="US1 AggregatorOrderId=”12345">
            <Item ItemID="C" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
    </OrderLines>

我使用了以下XSL,但它删除了所有原始的OrderLine元素,而且似乎没有对每个OrderLine执行此操作

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="OrderRelease">
        <OrderLine>
            <xsl:copy-of select="@*|OrderLine/@*" />
            <xsl:apply-templates /><!-- optional -->
        </OrderLine>
    </xsl:template>

    <xsl:template match="Order">
            <xsl:copy-of select="@*|OrderLine/@*" />
            <xsl:apply-templates /><!-- optional -->
    </xsl:template>
    <xsl:template match="Extn">
            <xsl:copy-of select="@*|OrderLine/@*" />
            <xsl:apply-templates /><!-- optional -->
    </xsl:template>
        <xsl:template match="OrderLine">
            <xsl:copy-of select="@*|OrderLine/@*" />
    </xsl:template>
    
    
</xsl:stylesheet>
xmlns:xsl=”http://www.w3.org/1999/XSL/Transform">
这个的输出是

<OrderLine EnterpriseCode="BRD"
           ReleaseNo="1234ABC"
           DocumentType="0001"
           SellerOrganizationCode="BU1"
           ShipNode="US1"
           OrderDate="2019-06-13T09:27:36-04:00"
           Action="CANCEL"
           OrderNo="1234ABC"
           ExtnWMSOrderNumber="123ADS"
           PrimeLineNo="3"
           SubLineNo="1"
           OrderedQty="0"/>

你可以这样做

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

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

  <xsl:template match="OrderLines">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="OrderLine">
    <xsl:copy>
      <xsl:copy-of select="@*"/> <!-- OrderLine attributes -->
      <xsl:copy-of select="../../@*"/> <!-- OrderRelease attributes -->
      <xsl:copy-of select="../../Order/@*"/> <!-- Order attributes -->
      <xsl:attribute name="AggregatorOrderId">12345</xsl:attribute>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="Item">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

12345

看到它在这里工作:

哇,这绝对是完美的。整个上午我的头都撞在墙上了。有没有办法忽略订单发布中的操作?将操作保持在订单行级别?如果使用XSLT 2+,可以执行类似“./../Order/@*除了@action”的操作。或者你可以像我为AggregatorOrderId属性所做的那样单独命名任何属性。非常感谢你的帮助,朋友!不客气。如果回答了您的问题,请将答案标记为已接受。