XSLT для замены XML значения элемента - PullRequest
1 голос
/ 05 апреля 2020

Я пытаюсь использовать 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>

Большое спасибо

1 Ответ

0 голосов
/ 05 апреля 2020

Как и в большинстве преобразований 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

...