XSL Применить шаблон ко всем элементам - PullRequest
1 голос
/ 13 сентября 2011

У меня есть следующий XML-документ:

<root>
    <object type="set">
        <name>Test1</name>
        <object type="set">
            <name>Test11</name>
            <object type="set">
                <name>Test111</name>
            </object>
        </object>
    </object>

    <object type="set">
        <name>Test2</name>
        <object type="set">
            <name>Test22</name>
        </object>
    </object>

    <object type="set">
        <name>Test3</name>
    </object>
</root>

и следующий XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<xsl:template match="//object[@type='set']">
    <p>
            <xsl:value-of select="name"/>   
    </p>
</xsl:template>

</xsl:stylesheet>

Каким-то образом // object [@ type = 'set'] выбирает только первое (Test1, Test2, Test3). Но я хочу выбрать все элементы (Test11, Test111, Test22).

Ответы [ 2 ]

2 голосов
/ 13 сентября 2011

Шаблон никогда не создается "сам по себе".

Вместо этого шаблон применяется только к списку узлов, который указан expression в инструкции <xsl:apply-templates select="expression"/>.

Также обратите внимание, что

<xsl:template match="//object[@type='set']">

эквивалентно;

<xsl:template match="object[@type='set']">

снова - шаблон не выбрать it соответствует .

Одно из решений этой проблемы :

Использование:

<xsl:apply-templates select="//object[@type='set']"/>

Все преобразование становится :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <html>
            <body>
                <xsl:apply-templates select="//object[@type='set']"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="object[@type='set']">
        <p>
            <xsl:value-of select="name"/>
        </p>
    </xsl:template>
</xsl:stylesheet>

, и оно дает желаемый, правильный результат :

<html>
   <body>
      <p>Test1</p>
      <p>Test11</p>
      <p>Test111</p>
      <p>Test2</p>
      <p>Test22</p>
      <p>Test3</p>
   </body>
</html>
1 голос
/ 13 сентября 2011

Ну, кроме того, я хочу сказать, что ваше выражение xpath действительно соответствует каждому объекту типа set.

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

Вы просто копируете значение первого вхождения атрибута «имя» и игнорируете его возможные дочерние элементы.

Возможное решение, которое вы намеревались решить, может быть:

<xsl:template match="//object[@type='set']">
<p>
        <xsl:value-of select="name"/>       
</p>
<xsl:for-each select=".//object[@type='set']">
<p>     
        <xsl:value-of select="name"/>                      
</p>
 </xsl:for-each></xsl:template>

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

Надеюсь, что смогу помочь, и извиняюсь за мой плохой английский:)

С наилучшими пожеланиями

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