XSLT:更改特定属性值

8

我是一名 XSLT 新手,有一个简单的任务:

假设我有以下 XML:

<Element1>
    <Element2 attr1="1"/>
</Element1>
<Element1 attr1="2"/>
<Element1>
    <Element2 attr1="2"/>
</Element1>

我想将XML转换为具有一个更改的相同XML:所有名为“attr1”的属性不管在哪里,都必须进行转换,例如“1”将变成“A”,“2”将变成“X”,即

<Element1>
    <Element2 attr1="A"/>
</Element1>
<Element1 attr1="X"/>
<Element1>
    <Element2 attr1="X"/>
</Element1>

我该如何达成这个目标?先谢过了!

4个回答

8
你可以定义要替换的字符和替换字符,然后使用translate函数。你可以使用以下XSLT代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:variable name="in">12</xsl:variable>
    <xsl:variable name="out">AX</xsl:variable>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@attr1">
        <xsl:attribute name="attr1">
            <xsl:value-of select="translate(., $in, $out)"/>
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

另一种方法:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@attr1">
        <xsl:choose>
            <xsl:when test=". = '1'">
                <xsl:attribute name="attr1">
                    <xsl:text>A</xsl:text>
                </xsl:attribute>
            </xsl:when>
            <xsl:when test=". = '2'">
                <xsl:attribute name="attr1">
                    <xsl:text>X</xsl:text>
                </xsl:attribute>
            </xsl:when>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>
<xsl:template match="@attr1">会匹配所有attr1属性,然后使用xsl:choose为该属性创建适当的值。

为了适应运行时的定制,将 xsl:variable 更改为 xsl:param - Mads Hansen

8

您没有提到当@attr=3时会发生什么,因此有一个otherwise子句,如果它不是所选值之一,就只需复制该值。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="@attr1">
  <xsl:attribute name="attr1">
    <xsl:choose>
      <xsl:when test=". = 1">
        <xsl:text>A</xsl:text>
      </xsl:when>
      <xsl:when test=". = 2">
        <xsl:text>X</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="." />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:attribute>
</xsl:template>
</xsl:stylesheet>

如果需要从外部获取值怎么办?也就是说,如何使用一个外部映射文件,其中将有“1”->“A”和“2”->“X”的映射关系? - Amol
@Amol 然后你可以使用 key 函数 引用外部文档来设置查找。 - Bob Vale
我提出了这个问题以获得更多的明确性。 - Amol

2
另一种方法是使用document函数:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:l="local"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@attr1">
        <xsl:attribute name="attr1">
            <xsl:value-of select="document('')//l:item[l:in = current()]/l:out"/>
        </xsl:attribute>
    </xsl:template>

    <xml xmlns="local">
        <item>
            <in>1</in>
            <out>A</out>
        </item>
        <item>
            <in>2</in>
            <out>X</out>
        </item>
    </xml>

</xsl:stylesheet>

使用文档的键查找不是更有效吗? - Bob Vale

1

xslt 2 version below works:

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@attr1[.='1']">
        <xsl:attribute name="attr1">
            <xsl:value-of select="replace(.,'1','A')"/>
        </xsl:attribute>
    </xsl:template>

    <xsl:template match="@attr1[.='2']">
        <xsl:attribute name="attr1">
            <xsl:value-of select="replace(.,'2','X')"/>
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接