仍在学习 XML/XSLT,所以如果我做了一些愚蠢的事情,请原谅我。
我正在尝试根据“类型”主列表(也在文件内)过滤 XML 文件的节点。我正在从包含主列表的节点创建一个变量,但是当我尝试在“包含”函数中引用该变量时,它没有正确过滤。
我在这里做错了什么?
XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<users>
<types>1600,1601,1602,1603</types>
<user><name>Joe</name><type>1600</type></user>
<user><name>Susan</name><type>1601</type></user>
<user><name>Alex</name><type>3</type></user>
<user><name>Jenny</name><type>4</type></user>
</users>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<users>
<!-- store type list in variable -->
<xsl:variable name="var_typelist" select="users/types"/>
<!-- cycle through users -->
<xsl:for-each select="users/user">
<!-- store user data in a variable -->
<xsl:variable name="var_user" select="*"></xsl:variable>
<!-- check if user type matches one in the list -->
<xsl:choose>
<xsl:when test="contains($var_typelist,type)">
<!-- rebuild file with user details -->
<users>
<xsl:copy-of select="$var_user"/>
</users>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</users>
</xsl:template>
</xsl:stylesheet>
我希望这会删除亚历克斯和珍妮,但它只是删除珍妮。似乎认为 Alex 的“3”在主列表中找到,但它是 1603。如果我从主列表中删除 1603,它也会过滤掉 Alex。
“包含”似乎是在查看主列表中的每个字符(1、6、0、3 等),而不是每种类型(1603)。如果是这样的话,我该如何让它查看每种类型?
如有任何建议,我们将不胜感激。
非常感谢, 艾伦
“包含”似乎正在查看主列表中的每个字符(1、6、0、3 等)
不,
contains()
函数正在查找一个字符串在另一个字符串中的出现情况。在您的示例中,字符串“3”is包含在字符串“1600,1601,1602,1603”中。
由于您似乎正在使用 XSLT 2.0,因此您可以简单地标记类型,然后进行直接比较:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/users">
<xsl:variable name="types" select="tokenize(types, ',')"/>
<users>
<xsl:copy-of select="user[type=$types]"/>
</users>
</xsl:template>
</xsl:stylesheet>
在 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:template match="/users">
<xsl:variable name="types" select="concat(',', types, ',')"/>
<users>
<xsl:copy-of select="user[contains($types, concat(',', type, ','))]"/>
</users>
</xsl:template>
</xsl:stylesheet>