我有一个xml文件,如下所示 的 propNode.xml
<NODES>
<NODE>
<NODELINE CLASS="Item" TYPE="Item" >
<ATTR_NODES>
<ATTR_NODE NAME="myName" />
<ATTR_NODE NAME="myDesc />
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item1" TYPE="Item1" >
<ATTR_NODES>
<ATTR_NODE NAME="myName1" />
<ATTR_NODE NAME="myDesc1" />
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item2" TYPE="Item2" >
<ATTR_NODES>
<ATTR_NODE NAME="myName2" />
<ATTR_NODE NAME="myDesc2" />
</ATTR_NODES>
</NODELINE>
</NODE>
</NODES>
我想阅读这个xml并使用它,我需要合并以下两个xml文件 的 source.xml
<NODES>
<NODE>
<NODELINE CLASS="Item" TYPE="Item" >
<ATTR_NODES>
<ATTR_NODE NAME="myName" VALUE="myNameValue" />
<ATTR_NODE NAME="myDesc" VALUE="test-myDescValue" />
<ATTR_NODE NAME="myId" VALUE="test-myIdValue" />
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item1" TYPE="Item1" >
<ATTR_NODES>
<ATTR_NODE NAME="myName1" VALUE="myNameValue1" />
<ATTR_NODE NAME="myDesc1" VALUE="myDescValue1"/>
<ATTR_NODE NAME="myId1" VALUE="myIdValue1" />
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item2" TYPE="Item2" >
<ATTR_NODES>
<ATTR_NODE NAME="myName2" VALUE="test-myNameValue2" />
<ATTR_NODE NAME="myDesc2" VALUE="myDescValue2"/>
<ATTR_NODE NAME="myId2" VALUE="test-myIdValue2" />
</ATTR_NODES>
</NODELINE>
</NODE>
</NODES>
target.xml
<NODES>
<NODE>
<NODELINE CLASS="Item" TYPE="Item" >
<ATTR_NODES>
<ATTR_NODE NAME="myName" VALUE="myNameValue" />
<ATTR_NODE NAME="myDesc" VALUE="myDescValue" />
<ATTR_NODE NAME="myId" VALUE="myIdValue" />
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item1" TYPE="Item1" >
<ATTR_NODES>
<ATTR_NODE NAME="myName1" VALUE="myNameValue1" />
<ATTR_NODE NAME="myDesc1" VALUE="myDescValue1"/>
<ATTR_NODE NAME="myId1" VALUE="myIdValue1" />
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item2" TYPE="Item2" >
<ATTR_NODES>
<ATTR_NODE NAME="myName2" VALUE="myNameValue2" />
<ATTR_NODE NAME="myDesc2" VALUE="myDescValue2"/>
<ATTR_NODE NAME="myId2" VALUE="myIdValue2" />
</ATTR_NODES>
</NODELINE>
</NODE>
</NODES>
条件是读取propNode.xml,如果@NAME的值在source.xml和target.xml中匹配,则需要比较source.xml和target.xml中@VALUE的值,并且输出xml应该如下创建:
desiredOutput.xml
<NODES>
<NODE>
<NODELINE CLASS="Item" TYPE="Item" >
<ATTR_NODES>
<ATTR_NODE NAME="myName" SRCVALUE="myNameValue" TGTVALUE="myNameValue" ISDIFF="false" />
<ATTR_NODE NAME="myDesc" SRCVALUE="test-myDescValue" TGTVALUE="myDescValue" ISDIFF="true" />
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item1" TYPE="Item1" >
<ATTR_NODES>
<ATTR_NODE NAME="myName1" SRCVALUE="myNameValue1" TGTVALUE="myNameValue1" ISDIFF="false" />
<ATTR_NODE NAME="myDesc1" SRCVALUE="myDescValue1" TGTVALUE="myDescValue1" ISDIFF="false" />
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item2" TYPE="Item2" >
<ATTR_NODES>
<ATTR_NODE NAME="myName2" SRCVALUE="test-myNameValue2" TGTVALUE="myNameValue2" ISDIFF="true" /> />
<ATTR_NODE NAME="myDesc2" SRCVALUE="myDescValue2" TGTVALUE="myDescValue2" ISDIFF="false" />
</ATTR_NODES>
</NODELINE>
</NODE>
</NODES>
如果在propNode.xml中选择了@NAME的值,则desiredOutput.xml应包含来自源和目标的@VALUE值。如果@VALUE的值不同,则@ISDIFF的值应为“true”,否则为“false”。
使用xslt可以完成整个操作吗?有什么比使用propNode.xml生成xsl然后将它应用于source.xml和target.xml以生成所需的输出?这个xsl怎么样?
答案 0 :(得分:1)
假设只需要测试ATTR_NODE
中存在的节点(propNode.xml
),以下XSLT应该完成这项工作:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="some.uri" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ATTR_NODE">
<xsl:variable name="NodeLine" select="../../@CLASS" />
<xsl:variable name="AttrName" select="@NAME" />
<xsl:variable name="SrcValue" select="document('source.xml')//NODELINE[@CLASS=$NodeLine]//ATTR_NODE[@NAME=$AttrName]/@VALUE" />
<xsl:variable name="TgtValue" select="document('target.xml')//NODELINE[@CLASS=$NodeLine]//ATTR_NODE[@NAME=$AttrName]/@VALUE" />
<xsl:element name="ATTR_NODE">
<xsl:attribute name="NAME">
<xsl:value-of select="$AttrName"/>
</xsl:attribute>
<xsl:attribute name="SRCVALUE">
<xsl:value-of select="$SrcValue" />
</xsl:attribute>
<xsl:attribute name="TGTVALUE">
<xsl:value-of select="$TgtValue" />
</xsl:attribute>
<xsl:attribute name="ISDIFF">
<xsl:value-of select="$SrcValue!=$TgtValue" />
</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
标识模板用于遍历和复制propNode
,对源和目标中的每个ATTR_NODE
检查VALUE
进行特殊处理,然后评估是否相等。我假设NODE_LINE/@CLASS
足以确定NODE_LINE
的身份 - 如果不是,那么您需要添加额外的检查,例如@TYPE
也是如此。
xslt针对propnode.xml
运行,source.xml
和target.xml
必须存在于同一文件夹中。
<强>输出强>
<?xml version="1.0" encoding="utf-8"?>
<NODES>
<NODE>
<NODELINE CLASS="Item" TYPE="Item">
<ATTR_NODES>
<ATTR_NODE NAME="myName" SRCVALUE="myNameValue" TGTVALUE="myNameValue" ISDIFF="false" />
<ATTR_NODE NAME="myDesc" SRCVALUE="test-myDescValue" TGTVALUE="myDescValue" ISDIFF="true" />"
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item1" TYPE="Item1">
<ATTR_NODES>
<ATTR_NODE NAME="myName1" SRCVALUE="myNameValue1" TGTVALUE="myNameValue1" ISDIFF="false" />
<ATTR_NODE NAME="myDesc1" SRCVALUE="myDescValue1" TGTVALUE="myDescValue1" ISDIFF="false" />
</ATTR_NODES>
</NODELINE>
<NODELINE CLASS="Item2" TYPE="Item2">
<ATTR_NODES>
<ATTR_NODE NAME="myName2" SRCVALUE="test-myNameValue2" TGTVALUE="myNameValue2" ISDIFF="true" />
<ATTR_NODE NAME="myDesc2" SRCVALUE="myDescValue2" TGTVALUE="myDescValue2" ISDIFF="false" />
</ATTR_NODES>
</NODELINE>
</NODE>
</NODES>