Как получить определенный тег из XML, чтобы поместить его в HTML с помощью XSLT?

#xslt

#xslt

Вопрос:

Мне нужно преобразовать XML, чтобы получить тег ‘fig’ из XML и поместить его в соответствующую перекрестную ссылку.

Ввод:

 <floats>
  <fig id=”fig1”>
    <p>First figure</p>
    <link locator=”fig1.tif”/>
  </fig>
  <fig id=”fig2”>
    <p>Second figure</p>
    <link locator=”fig2.tif”/>
  </fig>
</floats>
<body>
  <p>Paragraph 1<cross-ref refid=”fig1”>Fig. 1</cross-ref><float-anchor refid="fig1" /></p>
  <p>Paragraph 2<cross-ref refid=”fig2”>Fig. 2</cross-ref><float-anchor refid="fig2" /></p>
</body>
  

Вывод:

 <p class=”txt”>Paragraph 1<a href=”#fig1”>Fig. 1</a></p>
<div class=”figure” id=”fig1”>
  <p class=”fig”>First figure</p>
  <img src=”fig1.tif”/>
</div>
<p class=”txt”>Paragraph 2<a href=”#fig2”>Fig. 2</a></p>
<div class=”figure” id=”fig2”>
  <p class=”fig”>Second figure</p>
  <img src=”fig2.tif”/>
</div>
  

Не могли бы вы посоветовать мне это. Заранее спасибо.

Комментарии:

1. cross-ref и float-anchor мне кажется излишним, как они соотносятся?

2. В случае нескольких cross-ref s наличие float-anchor указывает, где должен быть размещен вызов.

Ответ №1:

попробуйте следующую таблицу стилей:

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:strip-space elements="*"/>

    <xsl:output indent="yes" omit-xml-declaration="yes"/>

    <xsl:variable name="Fig" select="root/floats"/>

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

    <xsl:template match="p">
        <p class="txt">
            <xsl:apply-templates select="@*|node()"/>
        </p>
        <xsl:if test="float-anchor">
            <xsl:for-each select="float-anchor">
                <xsl:apply-templates select="$Fig/fig[@id=current()/@refid]" mode="transfer"/>
            </xsl:for-each>
        </xsl:if>
    </xsl:template>

    <xsl:template match="floats|float-anchor"/>

    <xsl:template match="root|body">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="fig" mode="transfer">
        <div class="figure" id="{@id}">
            <xsl:apply-templates/>
        </div>
    </xsl:template>

    <xsl:template match="link">
        <img src="{@locator}"/>
    </xsl:template>

    <xsl:template match="cross-ref">
        <a href="#{@refid}">
            <xsl:apply-templates/>
        </a>
    </xsl:template>

</xsl:stylesheet>
  

поскольку ваш входной XML недопустим (отсутствует корневой узел), рассмотрите следующий входной XML:

 <?xml version="1.0" encoding="UTF-8"?>
<root>
    <floats>
        <fig id="fig1">
            <p>First figure</p>
            <link locator="fig1.tif"/>
        </fig>
        <fig id="fig2">
            <p>Second figure</p>
            <link locator="fig2.tif"/>
        </fig>
    </floats>
    <body>
        <p>Paragraph 1<cross-ref refid="fig1">Fig. 1</cross-ref><float-anchor refid="fig1" /></p>
        <p>Paragraph 2<cross-ref refid="fig2">Fig. 2</cross-ref><float-anchor refid="fig2" /></p>
    </body>
</root>
  

при применении к таблице стилей выше вывод:

 <p class="txt">Paragraph 1<a href="#fig1">Fig. 1</a>
</p>
<div class="figure" id="fig1">
    <p class="txt">First figure</p>
    <img src="fig1.tif"/>
</div>
<p class="txt">Paragraph 2<a href="#fig2">Fig. 2</a>
</p>
<div class="figure" id="fig2">
    <p class="txt">Second figure</p>
    <img src="fig2.tif"/>
</div>
  

Ответ №2:

Попробуйте, соответствует ли следующее преобразование вашим потребностям. Он еще не учитывает комментарий Джоэла М. Ламсена относительно cross-ref и float-anchor . Обновление: теперь это так.

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:transform 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="/">
    <xsl:apply-templates select="//body" />
</xsl:template>

<xsl:template match="p">
    <xsl:copy>
        <xsl:attribute name="class">text</xsl:attribute>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
    <xsl:apply-templates select="float-anchor" mode="float" />
</xsl:template>

<xsl:template match="cross-ref">
    <xsl:variable name="refid" select="@refid" />
    <xsl:element name="a">
        <xsl:attribute name="href">
            <xsl:value-of select="concat('#', $refid)" />
        </xsl:attribute>
        <xsl:value-of select="." />
    </xsl:element>
</xsl:template>

<xsl:template match="float-anchor" />

<xsl:template match="float-anchor" mode="float">
    <xsl:variable name="refid" select="@refid" />
    <xsl:element name="div">
        <xsl:attribute name="id"><xsl:value-of select="$refid" /></xsl:attribute>
        <xsl:attribute name="class">figure</xsl:attribute>
        <xsl:apply-templates select="//floats/fig[@id=$refid]/*" mode="float" />
    </xsl:element>
</xsl:template>

<xsl:template match="p" mode="float">
    <xsl:copy>
        <xsl:attribute name="class">fig</xsl:attribute>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<xsl:template match="link" mode="float">
    <xsl:element name="img">
        <xsl:attribute name="src"><xsl:value-of select="@locator" /></xsl:attribute>
    </xsl:element>
</xsl:template>
</xsl:transform>