使用XSLT基于现有值更改属性值

时间:2015-10-05 17:34:26

标签: xml xslt

我有一个XML文档如下

<Element>
    <Element1>
        <Element2 attr1="Horizontal"/>
    </Element1>
    <Element1 attr1="V"/>
    <Element1>
        <Element2 attr1="Island"/>
    </Element1>
</Element>

我希望有一个XSLT来转换XML,条件如下:

  1. 如果attr1值为“水平”或“H”,则必须将其替换为“H”
  2. 如果attr1值为“Vertical”或“V”,则必须将其替换为“V”
  3. 如果attr1值为“Island”或“ISL”,则必须将其替换为“ISL”
  4. 否则attr1中的相同值将显示为
  5. 这样生成的XML如下所示:

    <Element>
        <Element1>
            <Element2 attr1="H"/>
        </Element1>
        <Element1 attr1="V"/>
        <Element1>
            <Element2 attr1="ISL"/>
        </Element1>
    </Element>
    

    我有以下XSLT。这个或条件似乎不适用于此。我怎样才能改变它?

    <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=". ='Horizontal' or 'H'">
            <xsl:text>H</xsl:text>
          </xsl:when>
          <xsl:when test=". = 'Vertical' or 'V'">
            <xsl:text>V</xsl:text>
          </xsl:when>
         </xsl:choose>
       </xsl:attribute>
    </xsl:template>
    </xsl:stylesheet>
    

2 个答案:

答案 0 :(得分:3)

我会使用匹配模式进行条件处理:

shell

注意:尝试通过<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- Identity --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="@attr1[. = 'Horizontal']"> <xsl:attribute name="attr1">H</xsl:attribute> </xsl:template> <xsl:template match="@attr1[. = 'Vertical']"> <xsl:attribute name="attr1">V</xsl:attribute> </xsl:template> <xsl:template match="@attr1[. = 'Island']"> <xsl:attribute name="attr1">ISL</xsl:attribute> </xsl:template> </xsl:stylesheet> 设置属性值时,以下表单的覆盖 有效:< / p>

xsl:copy

@Abel在之前的评论中提供了一个简洁的解释,保留在这里:

  

属性没有子节点,因此 <xsl:template match="@attr1[. = 'Horizontal']"> <xsl:copy>H</xsl:copy> </xsl:template> 将创建副本   属性及其内容。然后,您将添加一个文本节点   该属性被默默忽略:&#34; the content is instantiated only for nodes of types that can have attributes or children (i.e. root nodes and element nodes).&#34; (其中&#39;内容&#39;   指序列构造函数)。

答案 1 :(得分:3)

而不是:

<xsl:when test=". ='Horizontal' or 'H'">

你应该使用:

<xsl:when test=". ='Horizontal' or . = 'H'">

或者简单地说:

<xsl:when test=". ='Horizontal'>

因为你真的不想改变&#34; H&#34;。

这是一个完整的例子:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity 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=". = 'Horizontal'">H</xsl:when>
            <xsl:when test=". = 'Vertical'">V</xsl:when>
            <xsl:when test=". = 'Island'">ISL</xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>