Печать текстовых узлов XSLT 1.0 по умолчанию - PullRequest
6 голосов
/ 22 февраля 2011

Я смотрел на XSL xsl: template match = "/" , но образец соответствия, вызвавший мой вопрос, там не упоминается.

У меня довольно сложная структура XML:

<?xml version="1.0" encoding="UTF-8"?>
<MATERIAL_DATA>
<LOG>
    <USER>Peter</USER>
    <DATE>2011-02-18</DATE>
    <MATERIALS>
        <item>
            <MATNR>636207</MATNR>
            <TEXTS>
                <item>
                    <TEXT>granola bar 40gx24</TEXT>
                </item>
            </TEXTS>
            <PRICES>
                <item>
                    <MATNR>636207</MATNR>
                    <COST>125.78</COST>
                </item>
            </PRICES>
            <SALESPRICES>
                <item>
                    <B01>
                        <MATNR>636207</MATNR>
                        <CURR>CZK</CURR>
                        <DATBI>9999-12-31</DATBI>
                        <DATAB>2010-10-05</DATAB>
                    </B01>
                    <B02>
                        <item>
                            <PRICE>477.60</PRICE>
                            <KUNNR>234567</KUNNR>
                        </item>
                    </B02>
                </item>
            </SALESPRICES>
        </item>
    </MATERIALS>
</LOG>
</MATERIAL_DATA>

Теперь, если я применю следующий XSLT, мой вывод выглядит правильно:

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

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

<xsl:template match="B02">
    <xsl:element name="Mi">
        <xsl:value-of select="item/KUNNR"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

Я получаю вывод:

<?xml version="1.0" encoding="UTF-8"?>
<Mi>234567</Mi>

Но если я применю XSLT:

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

<xsl:output method="xml" indent="yes" encoding="UTF-8"/>

<xsl:template match="/*">
    <xsl:element name="MenuItems">
        <xsl:apply-templates select="LOG/MATERIALS/item/SALESPRICES/item"/>
    </xsl:element>
 </xsl:template>

<xsl:template match="B02">
    <xsl:element name="Mi">
        <xsl:value-of select="item/KUNNR"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

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

<?xml version="1.0" encoding="UTF-8"?>
<MenuItems>

                        636207
                        CZK
                        9999-12-31
                        2010-10-05
<Mi>234567</Mi>
</MenuItems>

Все значения из элемента <B01> находятся на выходе! Но почему - я не соответствую <B01> !? Как работает

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

сделать вывод правильно? Все, что я делаю с этим, это сопоставление всех узлов или атрибутов и применение шаблонов ко всему или всем атрибутам. Но, по моему мнению, не должно иметь значения, когда я точно подхожу <B01>! Кто-нибудь знает, почему это происходит?

Спасибо за понимание и подсказки!

С уважением, Питер

Ответы [ 2 ]

15 голосов
/ 22 февраля 2011

XSLT включает следующие шаблоны по умолчанию ( среди прочих ):

<!-- applies to both element nodes and the root node -->
<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

<!-- copies values of text and attribute nodes through -->
<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

В вашей первой таблице стилей вы неявно сопоставляете все текстовые узлы с node(), переопределяя действие по умолчанию.Затем в шаблоне B2 вы выводите целевое значение и больше не применяете шаблоны, что останавливает обработку.

Во второй таблице стилей вы явно применяете шаблоны ко всем дочерним элементам LOG/MATERIALS/item/SALESPRICES/item, вызывая значение по умолчаниюшаблоны для обработки узлов, которые вы явно не обрабатываете.Поскольку вы явно обрабатываете B2 без применения шаблонов к его дочерним элементам, шаблоны по умолчанию никогда не вызываются для этих узлов.Но шаблоны по умолчанию применяются к дочерним элементам B1.

Добавление следующего шаблона во вторую таблицу стилей переопределит действие по умолчанию для текстовых узлов:

<xsl:template match="text()|@*"></xsl:template>

со следующим результатом:

<?xml version="1.0" encoding="UTF-8"?>
<MenuItems><Mi>234567</Mi></MenuItems>

Подробнее:

1 голос
/ 22 февраля 2011

Похоже, вы используете встроенный шаблон правил .

В частности, текстовое правило - оно будет копировать текстовые узлы, если не переопределено.

...