代码之家  ›  专栏  ›  技术社区  ›  user2093335

XSLT:基于现有属性值替换属性值

  •  1
  • user2093335  · 技术社区  · 6 年前

    如果是锚 <a class="section-ref"> 具有 @href 链接到 @id <div class="sect1"> 这是一个 <div class="chunk"> ,我想更改定位的值 @href @id号 父块的。我不知道如何找到 @id号 通过XSLT/XPath访问父块。

    XML:

    <book>
    <div>
        <p>In the <a class="section-ref" href="#i2398" id="i2397">next section</a>, we turn lorem ipsum.</p>
    </div>
    <div class="extend" id="i100949">
        <div class="check" id="i100950">
            <h1 class="title">Check</h1>
            <a class="other-ref" href="folder/other-ref.xml" id="i100953"></a>
        </div>
    </div>
    <div class="chunk" id="i100954">
        <h1 class="title">8.4</h1>
        <div class="other-section" id="i100955">
            <p id="i100956"> Lorem Ipsum</p>
        </div>
        <div class="sect1" id="i2398">
            <h1 class="title">Lorem Ipsum</h1>
            <p>Blah blah blah</p>
        </div>
    </div>
    

    XSLT:

    <!-- Identity template -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!--Change section-ref @href to parent chunk @id if they are @ids of a sect1-->
    
    <xsl:template match="a[@class='section-ref']">
        <xsl:variable name="section-id" select="substring-after(./@href, '#')"/>
        <xsl:variable name="section" select="$section-id = //div[@class='chunk']/div[@class='sect1']/@id"/>
    
        <xsl:choose>
            <xsl:when test="$section">
                <xsl:copy>
                    <xsl:attribute name="href" select="NEED XPATH HERE"/>
                    <xsl:apply-templates select="(node() | @*) except @href"/>
                </xsl:copy>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="node() | @*"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    

    所需输出:

    <book>
    <div>
        <p>In the <a class="section-ref" href="i100954" id="i2397">next section</a>, we turn lorem ipsum.</p>
    </div>
    <div class="extend" id="i100949">
        <div class="check" id="i100950">
            <h1 class="title">Check</h1>
            <a class="other-ref" href="folder/other-ref.xml" id="i100953"/>
        </div>
    </div>
    <div class="chunk" id="i100954">
        <h1 class="title">8.4</h1>
        <div class="other-section" id="i100955">
            <p id="i100956"> Lorem Ipsum</p>
        </div>
        <div class="sect1" id="i2398">
            <h1 class="title">Lorem Ipsum</h1>
            <p>Blah blah blah</p>
        </div>
    </div>
    

    请注意,节ref anchor@href值更改为父块的@id(i100954):

    <p>In the <a class="section-ref" href="i100954" id="i2397">next section</a>, we turn lorem ipsum.</p>
    
    3 回复  |  直到 6 年前
        1
  •  1
  •   Martin Honnen    6 年前

    我会定义一个键来引用 div 然后可以选择父div的id:

      <xsl:key name="ref" match="div[@class = 'sect1']" use="@id"/>
    
      <xsl:template match="a[@class = 'section-ref' and key('ref', substring(@href, 2))]/@href">
          <xsl:attribute name="{name()}" select="'#' || key('ref', substring(., 2))/parent::div/@id"/>
      </xsl:template>
    

    https://xsltfiddle.liberty-development.net/jyH9rM8 有一个示例,它是XSLT 3,但对于XSLT,您只需要使用 concat 而不是 || 运算符来构造新的属性值,然后需要使用标识转换模板(您已经拥有),而不是 xsl:mode

        2
  •  1
  •   zx485 potemkin    6 年前

    要填充示例的占位符“此处需要XPATH”,应使用

    ../../../div[@class='chunk']/@id
    

    或者用一个完整的表达:

    <xsl:attribute name="href" select="../../../div[@class='chunk']/@id" />
    

    这将为您提供所需的结果。

        3
  •  0
  •   imran    6 年前
    <xsl:template match="@*|node()">
           <xsl:copy>
               <xsl:apply-templates select="@*"/>
           </xsl:copy>
       </xsl:template>
        <xsl:template match="book">
            <xsl:element name="book">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:template>
        <xsl:template match="div">
            <xsl:element name="div">
                <xsl:apply-templates select="@*"/>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:template>
        <xsl:template match="p">
            <xsl:element name="p">
                <xsl:apply-templates select="@*"/>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:template>
        <xsl:template match="h1">
            <xsl:element name="h1">
                <xsl:apply-templates select="@*"/>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:template>
        <xsl:template match="a[@class='section-ref']">
            <xsl:element name="a">
            <xsl:attribute name="href">
                <xsl:value-of select="ancestor::div/following-sibling::div[@class='chunk']/@id"/>
            </xsl:attribute>
                <xsl:apply-templates select="@*"/>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:template>
    

    我试着用简单的方法得到你的结果