我需要通过比较2种XML中的数据来创建最终的XML
源XML:
<multimap:Messages xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge">
<multimap:Message1>
<FSE_BKLOG xmlns:ns1="http://www.w3.org/2005/Atom"
xmlns:ns2="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
xmlns:ns3="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<FSE_BKLOGType>
<FSE_ID>1</FSE_ID>
<TICKET_TYPE>T</TICKET_TYPE>
<T_COUNT>259</T_COUNT>
</FSE_BKLOGType>
<FSE_BKLOGType>
<FSE_ID>2</FSE_ID>
<TICKET_TYPE>T</TICKET_TYPE>
<T_COUNT>128</T_COUNT>
</FSE_BKLOGType>
<FSE_BKLOGType>
<FSE_ID>3</FSE_ID>
<TICKET_TYPE>T</TICKET_TYPE>
<T_COUNT>76</T_COUNT>
</FSE_BKLOGType>
</FSE_BKLOG>
</multimap:Message1>
<multimap:Message2>
<FSE_BKLOG>
<FSE_BKLOGType>
<FSE_ID>2</FSE_ID>
<T_COUNT>101</T_COUNT>
<TICKET_TYPE>T</TICKET_TYPE>
</FSE_BKLOGType>
<FSE_BKLOGType>
<FSE_ID>3</FSE_ID>
<T_COUNT>101</T_COUNT>
<TICKET_TYPE>T</TICKET_TYPE>
</FSE_BKLOGType>
<FSE_BKLOGType>
<FSE_ID>4</FSE_ID>
<T_COUNT>100</T_COUNT>
<TICKET_TYPE>T</TICKET_TYPE>
</FSE_BKLOGType>
</FSE_BKLOG>
</multimap:Message2>
</multimap:Messages>
我的要求是进入Message1 / FSE_BKLOG / FSE_BKLOGType / FSE_ID并 比较FSE_ID与Message2 / FSE_BKLOG / FSE_BKLOGType / FSE_ID中存在的FSE_ID 如果值匹配,则最终值xml将具有PUT,否则为POST
目标XML:
<Message>
<FSE_BKLOGType>
<Method>POST</Method>
<FSE_ID>1</FSE_ID>
<TICKET_TYPE>T</TICKET_TYPE>
<T_COUNT>259</T_COUNT>
</FSE_BKLOGType>
<FSE_BKLOGType>
<Method>PUT</Method>
<FSE_ID>2</FSE_ID>
<TICKET_TYPE>T</TICKET_TYPE>
<T_COUNT>128</T_COUNT>
</FSE_BKLOGType>
<FSE_BKLOGType>
<Method>PUT</Method>
<FSE_ID>3</FSE_ID>
<TICKET_TYPE>T</TICKET_TYPE>
<T_COUNT>76</T_COUNT>
</FSE_BKLOGType>
</FSE_BKLOG>
</Message>
这是我尝试的: 这给了我一些常见的信息,但是却错过了message1中出现的信息。
<xsl:template match="/">
<ns2:Messages>
<Message1>
<FSE_BKLOG>
<xsl:for-each select="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType">
<xsl:variable name="pos" select="position()"/>
<xsl:for-each select="/ns2:Messages/ns2:Message2/FSE_BKLOG/FSE_BKLOGType">
<xsl:choose>
<xsl:when test="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType[$pos]/FSE_ID = FSE_ID">
<FSE_BKLOGType>
<METHOD>PUT</METHOD>
<FSE_ID>
<xsl:value-of select="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType[$pos]/FSE_ID"/>
</FSE_ID>
<T_COUNT>
<xsl:value-of select="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType[$pos]/T_COUNT"/>
</T_COUNT>
<TICKET_TYPE>
<xsl:value-of select="/ns2:Messages/ns2:Message1/FSE_BKLOG/FSE_BKLOGType[$pos]/TICKET_TYPE"/>
</TICKET_TYPE>
</FSE_BKLOGType>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</FSE_BKLOG>
</Message1>
</ns2:Messages>
</xsl:template>
谢谢 亚坦
答案 0 :(得分:2)
我建议您使用 key 从输入XML的另一个分支中查找值。这是一个简单的示例:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:multimap="http://sap.com/xi/XI/SplitAndMerge">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="msg2" match="multimap:Message2/FSE_BKLOG/FSE_BKLOGType" use="FSE_ID" />
<xsl:template match="/multimap:Messages">
<Message>
<xsl:for-each select="multimap:Message1/FSE_BKLOG/FSE_BKLOGType">
<xsl:copy>
<Method>
<xsl:choose>
<xsl:when test="key('msg2', FSE_ID)">PUT</xsl:when>
<xsl:otherwise>POST</xsl:otherwise>
</xsl:choose>
</Method>
<xsl:copy-of select="*"/>
</xsl:copy>
</xsl:for-each>
</Message>
</xsl:template>
</xsl:stylesheet>
注意 :我没有费心删除复制到输出的冗余名称空间声明,因为(a)并不是您要问的重点(b)具体方法取决于您可以使用的XSLT版本(请参见:How to mimic copy-namespaces="no" in XSLT 1.0?)。