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

Xml 使用XSLT基于现有值更改属性值,xml,xslt,Xml,Xslt,我有一个XML文档,如下所示 <Element> <Element1> <Element2 attr1="Horizontal"/> </Element1> <Element1 attr1="V"/> <Element1> <Element2 attr1="Island"/> </Element1> </Element>

我有一个XML文档,如下所示

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

我希望使用XSLT在以下条件下转换XML:

  • 如果attr1值为“水平”或“H”,则必须将其替换为“H”
  • 如果attr1值为“垂直”或“V”,则必须将其替换为“V”
  • 如果attr1值为“孤岛”或“ISL”,则必须将其替换为“ISL”
  • 否则,attr1中的值将按原样显示
  • 因此,生成的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>
    
    
    H
    v
    
    我将使用匹配模式进行条件处理:

    <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>
    
    在先前的评论中提供了简洁的解释,保存在此处:

    属性没有子级,因此
    xsl:copy
    将创建一个副本 属性及其内容的。然后将文本节点添加到 默认忽略的属性:“”(其中“内容” 指序列构造函数)


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

    <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>
    
    在先前的评论中提供了简洁的解释,保存在此处:

    属性没有子级,因此
    xsl:copy
    将创建一个副本 属性及其内容的。然后将文本节点添加到 默认忽略的属性:“”(其中“内容” 指序列构造函数)

    而不是:

    <xsl:when test=". ='Horizontal' or 'H'">
    
    
    
    您应该使用:

    <xsl:when test=". ='Horizontal' or . = 'H'">
    
    
    
    或者简单地说:

    <xsl:when test=". ='Horizontal'>
    
    而不是:

    <xsl:when test=". ='Horizontal' or 'H'">
    
    
    
    您应该使用:

    <xsl:when test=". ='Horizontal' or . = 'H'">
    
    
    
    或者简单地说:

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

    您已经用四条规则描述了处理过程。XSLT是一种基于规则的语言,因此这些规则直接转换为XSLT模板规则,如@kjhughes所示。但是您的错误非常简单:您的测试条件表示
    test=“boolean(.='Horizontal')或boolean('H')”
    ,并且
    boolean('H')
    始终为真,因此测试始终通过。您已经用四条规则描述了处理过程。XSLT是一种基于规则的语言,因此这些规则直接转换为XSLT模板规则,如@kjhughes所示。但是您的错误非常简单:您的测试条件意味着
    test=“boolean(.='Horizontal')或boolean('H')”
    ,并且
    boolean('H')
    始终为真,因此测试始终通过。