【问题标题】:Moving elements of one XML node to a child node using xslt使用 xslt 将一个 XML 节点的元素移动到子节点
【发布时间】:2020-12-04 10:44:29
【问题描述】:

基本上我需要使用 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>

这个输出是

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

【问题讨论】:

    标签: java xml xslt


    【解决方案1】:

    你可以这样做。

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

    在这里看到它的工作:https://xsltfiddle.liberty-development.net/93nwMog

    【讨论】:

    • 哇,这绝对是完美的。整个早上都在用头撞墙。有什么方法可以忽略订单发布中的 Action 吗?将操作保留在 orderLine 级别?
    • 如果您使用 XSLT 2+,您可以执行“../../Order/@* except @action”之类的操作。或者你可以单独命名任何属性,就像我为 AggregatorOrderId 属性设置的那样。
    • 非常感谢您的帮助朋友!
    • 不客气。如果这回答了您的问题,请将答案标记为已接受。
    猜你喜欢
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 2021-09-05
    • 2021-03-20
    相关资源
    最近更新 更多