XSLT如何在匹配的目标时访问属性的值

时间:2018-05-09 21:45:02

标签: xml xslt

我发现很多关于如何在XSLT匹配元素时访问属性的值。但是,当匹配属性时,我似乎无法找到访问属性值的方法。

例如,这是我原始的xml文件的一部分:

    <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="">
      <mfrac>
        <mn>20</mn>
        <mn>60</mn>
      </mfrac>
      <mo>=</mo>
      <mfrac>
        <mi mathvariant="bold">x</mi>
        <mn>100</mn>
      </mfrac>
    </math>

这是我正在使用的模板(不起作用):

  <xsl:template match="mathml:math//mathml:mi/@mathvariant">
      <xsl:copy>
         <xsl:choose>
            <xsl:when test=".='bold'">
               <xsl:attribute name="mathvariant">
                  <xsl:value-of select="'bold-sans-serif'"/>
               </xsl:attribute>
            </xsl:when>
            <xsl:when test=".='italic'">
               <xsl:attribute name="mathvariant">
                  <xsl:value-of select="'sans-serif-italic'"/>
               </xsl:attribute>
            </xsl:when>
            <xsl:otherwise></xsl:otherwise>
         </xsl:choose>
      </xsl:copy>
   </xsl:template>

我想使用choose stmt根据它的值更改元素的mathvariant属性。我知道我需要匹配属性本身才能更改它的值(该部分有效),但我不知道如何在when语句中访问匹配属性的值。                       test =“。='bold'”不起作用。 如果匹配是属性,“点”并不意味着我认为它意味着什么。 我错过了什么?

2 个答案:

答案 0 :(得分:0)

如果要将属性mathvariant的值替换为其他值,可以使用以下模板。它们都与 indentity模板一起复制其余的XML。

<xsl:template match="mathml:mi/@mathvariant[.='bold']">
  <xsl:attribute name="mathvariant">
    <xsl:value-of select="'bold-sans-serif'"/>
  </xsl:attribute>
</xsl:template>   

<xsl:template match="mathml:mi/@mathvariant[.!='bold']">
  <xsl:attribute name="mathvariant">
    <xsl:value-of select="'sans-serif-italic'"/>
  </xsl:attribute>
</xsl:template>

因此,对于XSLT-1.0,请使用身份模板

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

对于XSLT-3.0,您可以使用

<xsl:mode on-no-match="shallow-copy" />

如果您想坚持xsl:choose,请将其放在xsl:attribute中并与相关元素匹配:

<xsl:template match="mathml:mi/@mathvariant">
  <xsl:attribute name="mathvariant">
      <xsl:choose>
          <xsl:when test=".='bold'">                 
              <xsl:value-of select="'bold-sans-serif'"/>
          </xsl:when>
          <xsl:otherwise>
              <xsl:value-of select="'sans-serif-italic'"/>                
          </xsl:otherwise>
      </xsl:choose>
  </xsl:attribute>
</xsl:template> 

答案 1 :(得分:0)

您的代码存在问题xsl:copy。当上下文项是属性时,xsl:copy会创建属性的副本,并忽略xsl:copy指令正文中的任何指令。尝试简单地删除xsl:copy开始和结束标记。我不保证会有效,因为我们还没有看到包含触发此模板规则的xsl:apply-templates的代码,但它至少应该确保执行xsl:choose

您对test=".='bold'"的使用完全可以:当上下文项是属性时,雾化上下文中的"."会为您提供属性的字符串值。