如何匹配XSLT中的XML内容?我将为您提供输入XML文件和预期输出以及我尝试过的内容:
input1.xml
<?xml version="1.0" ?>
<list1>
<value>1</value>
<value>2</value>
<value>3</value>
</list1>
input2.xml(编辑以显示顺序无关紧要)
<?xml version="1.0" ?>
<list2>
<value>3</value>
<value>1</value>
</list2>
所需的输出(编辑以显示顺序无关紧要):
1 match
2 no match
3 match
或其任何排列。
我尝试了什么:
<xsl:variable name="list1" select="document('./resources/input1.xml')"/>
<xsl:variable name="list2" select="document('./resources/input2.xml')"/>
<xsl:for-each select="$list1/list1/value">
<xsl:variable name="check"/>
<xsl:variable name="list1_value" select="."/>
<xsl:for-each select="$list2/list2/value">
<xsl:if test="$list1_value=.">
<xsl:variable name="check" select="1"/>
</xsl:if>
</xsl:for-each>
<xsl:choose>
<xsl:when test="$check='1'">
<xsl:value-of select="."/> match<br />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/> no match<br />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
当然这不起作用,因为它试图将变量用作变量:)
此外,您如何将较大的列表与应用于较小列表的XSLT相匹配:
XSLT应用于XML:
<?xml version="1.0" ?>
<list2>
<value>1</value>
<value>2</value>
</list2>
此列表作为变量导入:
<?xml version="1.0" ?>
<list1>
<value>1</value>
<value>2</value>
<value>3</value>
</list1>
同样的预期结果。谢谢!
答案 0 :(得分:2)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<my:doc2>
<list2>
<value>1</value>
<value>2</value>
</list2>
</my:doc2>
<xsl:variable name="vDoc2"
select="document('')/*/my:doc2/*"/>
<xsl:template match="/*/*">
<xsl:value-of select="concat('
 ',.,' ')"/>
<xsl:variable name="vPos" select="position()"/>
<xsl:if test="not(. = $vDoc2/*[position()=$vPos])">
<xsl:text>no </xsl:text>
</xsl:if>
<xsl:text>match</xsl:text>
</xsl:template>
</xsl:stylesheet>
应用于第一个提供的XML文档时:
<list1>
<value>1</value>
<value>2</value>
<value>3</value>
</list1>
会产生想要的正确结果:
1 match
2 match
3 no match
更新:相同的转换,但有两个不同的XML文件:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pDoc1" select="'/temp/list1.xml'"/>
<xsl:param name="pDoc2" select="'/temp/list2.xml'"/>
<xsl:variable name="vDoc1"
select="document($pDoc1)/*"/>
<xsl:variable name="vDoc2"
select="document($pDoc2)/*"/>
<xsl:template match="/">
<xsl:apply-templates select="$vDoc1/*"/>
</xsl:template>
<xsl:template match="/*/*">
<xsl:value-of select="concat('
 ',.,' ')"/>
<xsl:variable name="vPos" select="position()"/>
<xsl:if test="not(. = $vDoc2/*[position()=$vPos])">
<xsl:text>no </xsl:text>
</xsl:if>
<xsl:text>match</xsl:text>
</xsl:template>
</xsl:stylesheet>
Update2 :当要比较的较短元素列表是源XML文档时,OP还需要一个解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<my:doc2>
<list2>
<value>1</value>
<value>2</value>
<value>3</value>
</list2>
</my:doc2>
<xsl:variable name="vDoc1" select="/*"/>
<xsl:variable name="vDoc2"
select="document('')/*/my:doc2/*"/>
<xsl:template match="/">
<xsl:apply-templates select="$vDoc2/*"/>
</xsl:template>
<xsl:template match="value">
<xsl:value-of select="concat('
 ',.,' ')"/>
<xsl:variable name="vPos" select="position()"/>
<xsl:if test="not(. = $vDoc1/*[position()=$vPos])">
<xsl:text>no </xsl:text>
</xsl:if>
<xsl:text>match</xsl:text>
</xsl:template>
</xsl:stylesheet>
在此源XML文档上应用此转换时:
<list1>
<value>1</value>
<value>2</value>
</list1>
再次生成想要的正确结果:
1 match
2 match
3 no match
Update3 :现在是OP的第三次修改:两个列表中元素的顺序无关紧要......
解决方案更简单:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<my:doc2>
<list2>
<value>1</value>
<value>2</value>
<value>3</value>
</list2>
</my:doc2>
<xsl:variable name="vDoc1" select="/*"/>
<xsl:variable name="vDoc2"
select="document('')/*/my:doc2/*"/>
<xsl:template match="/">
<xsl:apply-templates select="$vDoc2/*"/>
</xsl:template>
<xsl:template match="value">
<xsl:value-of select="concat('
 ',.,' ')"/>
<xsl:if test="not(. = $vDoc1/*)">
<xsl:text>no </xsl:text>
</xsl:if>
<xsl:text>match</xsl:text>
</xsl:template>
</xsl:stylesheet>