根据XSLT的属性修改数据



编辑:

<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>

最新更新