XSLT:如果XML值存在于另一个节点中,则替换该值



我需要您帮助解决以下需求。

我有这个输入XML:

<?xml version='1.0' encoding='UTF-8'?>
<multi>
<batchPartResponse>
<batchQueryPartResponse>
<body>
<ObjectIdentifierMappingCollection>
<ObjectIdentifierMapping>
<LocalObjectID>ABC</LocalObjectID>
<RemoteObjectID>100828</RemoteObjectID>
</ObjectIdentifierMapping>
</ObjectIdentifierMappingCollection>
</body>
</batchQueryPartResponse>
<batchQueryPartResponse>
<body>
<ObjectIdentifierMappingCollection>
<ObjectIdentifierMapping>
<LocalObjectID/>
<RemoteObjectID>100666</RemoteObjectID>
</ObjectIdentifierMapping>
</ObjectIdentifierMappingCollection>
</body>
</batchQueryPartResponse>
</batchPartResponse>
<root>
<CustomerPaymentInfo>
<PaymentForeCastAndOverDues>
<CustomerCode>100828</CustomerCode>
</PaymentForeCastAndOverDues>
</CustomerPaymentInfo>
<CustomerPaymentInfo>
<PaymentForeCastAndOverDues>
<CustomerCode>100666</CustomerCode>
</PaymentForeCastAndOverDues>
</CustomerPaymentInfo>
</root>
</multi>

我想做的是:如果//PaymentForeCastAndOverDues/CustomerCode=//ObjectIdentifierMapping/RemoteObjectID,则用LocalObjectID替换CustomerCode,如果LocalObjectID为null,则不替换。

预期结果是:

<?xml version='1.0' encoding='UTF-8'?>
<multi>
<batchPartResponse>
<batchQueryPartResponse>
<body>
<ObjectIdentifierMappingCollection>
<ObjectIdentifierMapping>
<LocalObjectID>ABC</LocalObjectID>
<RemoteObjectID>100828</RemoteObjectID>
</ObjectIdentifierMapping>
</ObjectIdentifierMappingCollection>
</body>
</batchQueryPartResponse>
<batchQueryPartResponse>
<body>
<ObjectIdentifierMappingCollection>
<ObjectIdentifierMapping>
<LocalObjectID/>
<RemoteObjectID>100666</RemoteObjectID>
</ObjectIdentifierMapping>
</ObjectIdentifierMappingCollection>
</body>
</batchQueryPartResponse>
</batchPartResponse>
<root>
<CustomerPaymentInfo>
<PaymentForeCastAndOverDues>
<CustomerCode>ABC</CustomerCode>
</PaymentForeCastAndOverDues>
</CustomerPaymentInfo>
<CustomerPaymentInfo>
<PaymentForeCastAndOverDues>
<CustomerCode>100666</CustomerCode>
</PaymentForeCastAndOverDues>
</CustomerPaymentInfo>
</root>
</multi>

你能分享一下你的建议吗?

提前谢谢。

我想你想做的是:

XSLT 1.0

<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"/>
<xsl:strip-space elements="*"/>
<xsl:key name="CustomerKey" match="ObjectIdentifierMapping" use="RemoteObjectID" /> 
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CustomerCode">
<xsl:variable name="objID" select="key('CustomerKey', .)/LocalObjectID" />
<xsl:copy>
<xsl:choose>
<xsl:when test="string($objID)">
<xsl:value-of select="$objID"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

p.S.如果需要,可以将第二个模板缩短为:

<xsl:template match="CustomerCode">
<xsl:copy>
<xsl:value-of select="(key('CustomerKey', .)/LocalObjectID[string(.)] | .)[1]"/>
</xsl:copy>
</xsl:template>

就我个人而言,我更喜欢更长、可读性更强的版本。

最新更新