XSLT匹配模板以仅更改一次属性

时间:2012-05-05 00:00:32

标签: xslt match

我有一个具有特定属性(myId)的文档,只要值为零,就需要更新该值。该文件看起来像这样

<?xml version="1.0" encoding="UTF-8"?><Summary>
 <Section myId="0">
  <Section myId="0">
   <Para>...</Para>
  </Section>
  <Section myId="5">
   <Para>...</Para>
  </Section>
 </Section>
</Summary>

我使用模板匹配属性myId,以便将其设置为从调用程序传递的唯一ID,但我只想匹配文档中的一个属性。任何其他值为零的属性都将通过传递不同的ID进行更新。 我正在使用的模板如下所示:

 <xsl:template        match  = '@myId[.="0"]'>
  <xsl:attribute name = "{name()}">
   <xsl:value-of select = "$addValue"/>
  </xsl:attribute>
 </xsl:template>

值addValue是从调用程序传递的全局参数。 我已经在当天的大部分时间里搜索了答案,但我无法仅将此模板应用一次。输出将myId值替换为addValue的内容。 我试图匹配'@myId [。“0”] [1]'并且我试图使用position()函数进行匹配,但我的模板总是应用于所有零的myId属性。 / p>

是否可以仅应用一次匹配模板?

1 个答案:

答案 0 :(得分:1)

  

是否可以仅应用一次匹配模板?

  1. 是否应用模板取决于导致选择执行模板的xsl:apply-templates

  2. 另外,匹配模式的确定方式可以保证模板只匹配文档中的一个特定节点。

  3. 以下是您可以做的事情

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:param name="pNewIdValue" select="9999"/>
    
    
     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match=
     "Section
       [@myId = 0
      and
        not((preceding::Section | ancestor::Section)
                     [@myId = 0]
           )
       ]/@myId">
      <xsl:attribute name="myId"><xsl:value-of select="$pNewIdValue"/></xsl:attribute>
     </xsl:template>
    </xsl:stylesheet>
    

    将此转换应用于提供的XML文档

    <Summary>
        <Section myId="0">
            <Section myId="0">
                <Para>...</Para>
            </Section>
            <Section myId="5">
                <Para>...</Para>
            </Section>
        </Section>
    </Summary>
    

    产生了想要的正确结果:

    <Summary>
       <Section myId="9999">
          <Section myId="0">
             <Para>...</Para>
          </Section>
          <Section myId="5">
             <Para>...</Para>
          </Section>
       </Section>
    </Summary>