首页 > 解决方案 > XSLT 替换 XML 元素值

问题描述

如果第二个元素值不为空,我正在尝试使用 XSLT 并用另一个元素替换 xml 元素值。在下面的示例中,我需要将Item标记值替换为ItemMaster-CustomChar10标记值,前提是它存在

<WmsShippingResultOutSiEs>
    <RecordId>6</RecordId>
    <ShipmentTransactionId>146</ShipmentTransactionId>
    <OutboundOrder>ERIC_1</OutboundOrder>
    <WmsShippingResultLineOutSiEs>
        <Line>
            <RecordId>6</RecordId>
            <ShipmentLineSequence>1</ShipmentLineSequence>
            <Item>BMS9</Item>
            <ItemMaster-CustomChar10>BMS9ALIAS</ItemMaster-CustomChar10>
            <WmsShippingResultLineDetailOutSiEs>
                <Line>
                    <ShipmentLineSequence>1</ShipmentLineSequence>
                    <ShipmentLineDetailTransactionId>143</ShipmentLineDetailTransactionId>
                </Line>
            </WmsShippingResultLineDetailOutSiEs>
        </Line>
        <Line>
            <RecordId>6</RecordId>
            <ShipmentLineSequence>2</ShipmentLineSequence>
            <Item>BMS10</Item>
            <ItemMaster-CustomChar10/>
            <WmsShippingResultLineDetailOutSiEs>
                <Line>
                    <ShipmentLineSequence>1</ShipmentLineSequence>
                    <ShipmentLineDetailTransactionId>144</ShipmentLineDetailTransactionId>
                </Line>
                <Line>
                    <ShipmentLineSequence>2</ShipmentLineSequence>
                    <ShipmentLineDetailTransactionId>145</ShipmentLineDetailTransactionId>
                </Line>
            </WmsShippingResultLineDetailOutSiEs>
        </Line>
    </WmsShippingResultLineOutSiEs>
</WmsShippingResultOutSiEs>

我期待有这样的结果

<WmsShippingResultOutSiEs>
    <RecordId>6</RecordId>
    <ShipmentTransactionId>146</ShipmentTransactionId>
    <OutboundOrder>ERIC_1</OutboundOrder>
    <WmsShippingResultLineOutSiEs>
        <Line>
            <RecordId>6</RecordId>
            <ShipmentLineSequence>1</ShipmentLineSequence>
            <Item>BMS9ALIAS</Item>
            <ItemMaster-CustomChar10>BMS9ALIAS</ItemMaster-CustomChar10>
            <WmsShippingResultLineDetailOutSiEs>
                <Line>
                    <ShipmentLineSequence>1</ShipmentLineSequence>
                    <ShipmentLineDetailTransactionId>143</ShipmentLineDetailTransactionId>
                </Line>
            </WmsShippingResultLineDetailOutSiEs>
        </Line>
        <Line>
            <RecordId>6</RecordId>
            <ShipmentLineSequence>2</ShipmentLineSequence>
            <Item>BMS10</Item>
            <ItemMaster-CustomChar10/>
            <WmsShippingResultLineDetailOutSiEs>
                <Line>
                    <ShipmentLineSequence>1</ShipmentLineSequence>
                    <ShipmentLineDetailTransactionId>144</ShipmentLineDetailTransactionId>
                </Line>
                <Line>
                    <ShipmentLineSequence>2</ShipmentLineSequence>
                    <ShipmentLineDetailTransactionId>145</ShipmentLineDetailTransactionId>
                </Line>
            </WmsShippingResultLineDetailOutSiEs>
        </Line>
    </WmsShippingResultLineOutSiEs>
</WmsShippingResultOutSiEs>

所有其他元素需要不应该受到影响。是否有可能递归地做到这一点?

我下面的 XSLT 代码不起作用

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="no"/>
<!-- identity template -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:for-each select="//WmsShippingResultLineDetailOutSiEs/Lines">
    <xsl:variable name="host_item" select="ItemMaster-CustomChar10"/>
    <xsl:if test="ItemMaster-CustomChar10 !=''">
        <Item>
            <xsl:value-of select="$host_item"/>
        </Item>
    </xsl:if>
</xsl:for-each>

非常感谢

标签: xslt-2.0

解决方案


与大多数 XML 到 XML 的转换一样,我建议使用身份转换作为起点,然后为要更改的元素添加一个模板:

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

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

  <xsl:template match="Line[ItemMaster-CustomChar10[normalize-space()]]/Item">
      <xsl:copy>
          <xsl:value-of select="../ItemMaster-CustomChar10"/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

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


推荐阅读