编辑:
<hero renown="null">John Doe</hero>
<hero gender="%women">"Poppin's</hero>
<hero gender="%God">Till</hero>
非常感谢您的回答,我可以得到理想的结果。除一个例外...对于其中一个属性,其价值是"%妇女"。我尝试了A,还有更多但没有结果...
我希望我可以使用XSLT,在数据XML中选择只有具有"女性"属性的元素,因此不能保留其他属性。我有以下代码:
<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>
此转换:
<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()
中 - 删除这些字符。
检查此代码: -
<?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>
您需要做的是....
<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>
<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>