XSLT: заменить значение атрибута на основе существующего значения атрибута - PullRequest
0 голосов
/ 10 мая 2018

Если якорь <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>

Обратите внимание, что значение @href привязки section-ref изменяется на @id родительского чанка (i100954):

<p>In the <a class="section-ref" href="i100954" id="i2397">next section</a>, we turn lorem ipsum.</p>

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Я бы определил ключ для ссылки на div, а затем вы можете выбрать идентификатор родительского div:

  <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.

0 голосов
/ 10 мая 2018
<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>

Я попытался получить ваш вывод простым способом

0 голосов
/ 10 мая 2018

Чтобы заполнить заполнитель "НУЖНО XPATH ЗДЕСЬ" вашего примера, вы должны использовать

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

или в целом выражении:

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

Это дает желаемый результат.

...