使用XSLT根据属性修改数据

时间:2019-07-01 15:23:24

标签: xml xslt

编辑:

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

4 个答案:

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