проблема с использованием метода xsl для каждого - PullRequest
3 голосов
/ 30 ноября 2009

Используя XSL, я пытаюсь включить этот XML:

<book><title>This is a <b>great</b> book</title></book>

в этот XML:

<book>This is a <bold>great</bold> book</book>

используя этот xsl:

<xsl:for-each select="book/title/*">
<xsl:choose>
    <xsl:when test="name() = 'b'">
        <bold>
            <xsl:value-of select="text()"/>
        </bold>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="text()"/>
    </xsl:otherwise>
</xsl:choose>
</xsl:for-each>

но мой вывод выглядит так:

<book><bold>great</bold></bold>

Может кто-нибудь объяснить, почему корневой текст <title> теряется? Я полагаю, что моё утверждение для каждого выбора может потребоваться изменить, но я не могу понять, что должно быть.

Имейте в виду, что я не могу использовать <xsl:template match> из-за сложности моей таблицы стилей.

Спасибо!

Ответы [ 2 ]

7 голосов
/ 30 ноября 2009

Это выражение XPath:

book/title/*

означает «все дочерние элементы из book/title». В вашем случае book/title имеет 3 дочерних узла :

  • Текстовый узел: This is a
  • Элемент узла: <b>...</b>
  • Текстовый узел: book

Как видите, только один из них является элементом и выбирается. Если вы хотите получить все дочерние узлы, как текст, так и элементы, используйте это:

book/title/node()

Если вы хотите получить текстовые узлы отдельно, используйте это:

book/title/text()
1 голос
/ 30 ноября 2009

Хотя Павел Минаев дал ответ на вопрос, , следует отметить, что этот вопрос демонстрирует очень плохой подход (возможно, из-за отсутствия опыта) к обработке XSLT .

Задача может быть выполнена элегантно, что демонстрирует мощь XSLT:

Когда вышеуказанное преобразование применяется к предоставленному документу XML:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>
    <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="title">
      <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="title/b">
      <bold>
       <xsl:apply-templates/>
      </bold>
    </xsl:template>
</xsl:stylesheet>

желаемый результат выдается:

<book><title>This is a <b>great</b> book</title></book>

Это хорошая иллюстрация одного из базовых шаблонов проектирования XSLT - переопределение правила идентификации для переименования / выравнивания элемента .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...