XSL-преобразование, генерирующее выходные данные из других узлов - PullRequest
3 голосов
/ 12 марта 2010

У меня есть следующий шаблон XSL (я опустил шаблон для Organization, дайте мне знать, если это необходимо):

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">     
<xsl:output method="html" indent="yes" omit-xml-declaration="yes"/>

<xsl:template match="SOAP-ENV:Body/*[local-name()='Publisher']">
    <html>      
        <xsl:call-template name="body" />
    </html>     
</xsl:template>
    <xsl:template name="body">
    <BODY>
        <br/>
        <center>
            <font face="arial" size="2">
                <b>Publisher <xsl:value-of select="*[local-name()='Organization']/*[local-name()='PublisherData']/*[local-name()='PublisherName']"/>
                </b>
            </font>
        </center>
        <br/>
        <xsl:apply-templates select="*[local-name()='Organization']"/>
    </BODY>
</xsl:template>
</xsl:stylesheet>

Предыдущий шаблон генерирует вывод, который я хочу, он генерирует теги, содержащие вывод, сгенерированный шаблоном "body". У меня проблема в том, что перед открывающим тегом я получаю текстовый вывод с предыдущего узла. Не уверен, почему это происходит, так как я не выбираю эти другие узлы. Например:

<SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <SOAP-ENV:Header>
            <n1>abc</n1>
                <n2>def</n2>
        </SOAP-ENV:Header>
        <SOAP-ENV:Body>
            <Publisher>
                          <!--Child nodes here -->
                    </Publisher>
            </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

Учитывая предыдущий пример XML-фрагмента, мой вывод будет содержать то, что я ожидал бы от форматирования элемента Publisher, но я также получаю текстовые узлы дочерних элементов узла SOAP-ENV: Header.

Я хочу преобразовать только содержимое элемента Publisher, но в выводе я получу:

abc
def
//Expected output transforming Publisher goes here

Мой вопрос: почему выбираются abc и def?

1 Ответ

3 голосов
/ 12 марта 2010

Выход генерируется из-за встроенных шаблонных правил , которые:

  • копировать текстовые узлы для вывода
  • применять шаблоны к элементам

Соответствующий раздел Рекомендации XSLT 1.0 включен ниже.

Возможно, вы просто захотите шаблон ничего не делать для SOAP-ENV: заголовок.

<xsl:template match="SOAP-ENV:Header">
</xsl:template>

Некоторые элементы в вашем исходном документе не находятся в пространстве имен. В выражении XPath элементы, которые не имеют пространства имен, могут указываться по их буквальному локальному имени. Вам нужно использовать local-name(), только если вы не знаете пространства имен для элемента.

Вот модифицированная версия вашей таблицы стилей. Он начинается с шаблона, соответствующего /, а затем явно выбирает нужные нам узлы.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

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

    <xsl:template match="/">
        <html>      
            <xsl:apply-templates select="SOAP-ENV:Body/Publisher" />
        </html>     
    </xsl:template>

    <xsl:template name="Publisher">
        <body>
            <br/>
            <center>
                <font face="arial" size="2">
                    <b>
                        <xsl:text>Publisher </xsl:text>
                        <xsl:value-of select="Organization/PublisherData/PublisherName"/>
                    </b>
                </font>
            </center>
            <br/>
            <xsl:apply-templates select="Organization"/>
        </body>
    </xsl:template>
</xsl:stylesheet>

Встроенные правила шаблонов

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

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

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

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

Также есть встроенное шаблонное правило для текстовых и атрибутных узлов, которые копирует текст через:

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

Встроенное шаблонное правило для инструкции по обработке и комментарии это ничего не делать.

<xsl:template match="processing-instruction()|comment()"/>

Встроенное шаблонное правило для Узлы пространства имен тоже ничего не делают. Там нет шаблона, который может соответствовать узел пространства имен; Итак, встроенный шаблонное правило - единственный шаблон правило, которое применяется для пространства имен узлы.

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

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