编辑:
<hero renown="null">John Doe</hero>
<hero gender="%women">"Poppin's</hero>
<hero gender="%God">Till</hero>
非常感谢您的回答,我可以得到理想的结果。除一个例外...对于属性之一,其值为“%women”。我尝试了,还有更多但没有结果...
我希望我可以使用XSLT在我的数据xml中仅选择具有“ women”属性的元素,因此不要保留其他元素。 我有以下代码:
<hero renown="null">John Doe</hero>
<hero gender="women">"Poppin's</hero>
<hero type="God">Till</hero>
我想要这个:
<women>Poppin's</women>
<god>Till</god>
这是我已经尝试过的:
<xsl:for-each select=".//hero">
<xsl:if test = "attribut = 'gender'">
<xsl:element name="{@gender}">
<xsl:value-of select="$hero"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
答案 0 :(得分:2)
此转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="hero[@gender='women']">
<women><xsl:value-of select="."/></women>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
应用于所提供的XML片段(包装到顶部元素中以使其格式正确的XML文档)
<heroes>
<hero renown="null">John Doe</hero>
<hero gender="women">Poppin's</hero>
<hero type="God">Till</hero>
</heroes>
产生想要的正确结果:
<women>Poppin's</women>
更新: OP更改了问题,指出:
我有很多标签,其属性值中包含%
这是一个通用解决方案,该解决方案从gender
属性的值中删除所有非名称字符,并构造一个以该结果为名称的元素:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vNameChars" select=
"'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.'"/>
<xsl:template match="hero[@gender]">
<xsl:element name=
"{translate(@gender, translate(@gender, $vNameChars, ''), '')}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
此转换应用于以下XML文档:
<heroes>
<hero renown="null">John Doe</hero>
<hero gender="%women">"Poppin's</hero>
<hero gender="me$n">"Poppin's</hero>
<hero gender="%God">Till</hero>
<hero gender="AllValid">Hello</hero>
</heroes>
产生了所需的正确结果:
<women>"Poppin's</women>
<men>"Poppin's</men>
<God>Till</God>
<AllValid>Hello</AllValid>
说明:
我们使用了由迈克尔·凯(Michael Kay)首次提出的 double-translate 技术,查找名称中所有无效的包含字符,并在外部translate()
中删除这些字符。
答案 1 :(得分:1)
您需要做的是这个。...
<xsl:for-each select=".//hero">
<xsl:if test="@gender='women'">
<xsl:element name="{@gender}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:for-each>
或者更好的方法是将条件移动到xsl:for-each
中,以允许删除xsl:if
<xsl:for-each select=".//hero[@gender='women']">
<xsl:element name="{@gender}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
也可以这样做,因为当您现在只选择一个性别时,不需要动态元素名称
<xsl:for-each select=".//hero[@gender='women']">
<women>
<xsl:value-of select="."/>
</women>
</xsl:for-each>
答案 2 :(得分:1)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="hero[contains(@gender, 'women')]">
<women><xsl:value-of select="."/></women>
</xsl:template>
<xsl:template match="hero[contains(@gender, 'God')]">
<God><xsl:value-of select="."/></God>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
答案 3 :(得分:1)
检查此代码:-
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="hero">
<xsl:for-each select="@*">
<xsl:element name="{translate(., '%', '')}">
<xsl:value-of select="..//node()"/>
</xsl:element>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>