Как преобразовать и изменить (!) Вложенные теги с помощью XSLT?

xslt nested transformation xpath-1.0

24 просмотра

1 ответ

Возьмите этот XML в качестве примера ...

<list>
  <header>
    something
  </header>
  <main>
    <p>
      (1) nothing <b>special</b> at all.
    </p>
    <p>
      (1a) and <b>another</b> thing.
    </p>
  </main>
</list>

Должен быть преобразован в ...

<list>
  <header>
    something
  </header>
  <aside>
    <para nr="(1)">
      nothing <u>special</u> at all.
    </para>
    <para nr="(1a)">
      and <u>another</u> thing.
    </para>
  </aside>
</list>

Этот ответ Stackoverflow был моей отправной точкой ...

На данный момент у меня нет реального подхода к решению проблемы. Я бы предпочел не цитировать мои предыдущие неудачи ...

Автор: Denis Giffeler Источник Размещён: 31.07.2019 03:11

Ответы (1)


1 плюс

Решение

Я не помню, чтобы я отвечал на этот ссылочный вопрос, но я дал ответ. Вам просто нужно реализовать ряд правил ...

  1. Конвертировать mainвaside
  2. Для каждого pтега добавьте nrатрибут во вновь созданный paraтег на основе значения в скобках в первом дочернем текстовом элементе
  3. Преобразовать bтеги под pэлементом вu

Второй вариант немного сложен, но может быть достигнут с помощью этого шаблона, который использует некоторые манипуляции со строками для извлечения числа в скобках.

<xsl:template match="p">
    <para nr="{substring-before(substring-after(text()[1], '('), ')')}">
        <xsl:apply-templates select="@*|node()"/>
    </para>
</xsl:template>

(Также обратите внимание на использование шаблонов значений атрибутов для создания атрибута)

Вам также понадобится связанный шаблон, чтобы удалить номер из первого текстового узла

<xsl:template match="p/text()[1]">
    <xsl:value-of select="substring-after(., ')')" />
</xsl:template>

Преобразовать bв uгораздо проще (это предполагает, что нужно изменить только те bэлементы, pкоторые находятся под)

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

Там будет аналогичный шаблон для изменения mainнаaside

Попробуйте это XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />

    <!-- This is the Identity Transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

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

    <xsl:template match="p">
        <para nr="{substring-before(substring-after(text()[1], '('), ')')}">
            <xsl:apply-templates select="@*|node()"/>
        </para>
    </xsl:template>

    <xsl:template match="p/text()[1]">
        <xsl:value-of select="substring-after(., ')')" />
    </xsl:template>

    <xsl:template match="p/b">
        <u>
            <xsl:apply-templates select="@*|node()"/>
        </u>
    </xsl:template>
</xsl:stylesheet>
Автор: Tim C Размещён: 28.09.2018 08:15
Вопросы из категории :
32x32