xslt-копия без детей - PullRequest
5 голосов
/ 25 января 2011

Привет, у меня есть XML-документ Sitemap, который выглядит примерно так

<pagenode title="home" url="~/" fornavbar="true">
 <pagenode title="admin" url="~/admin" fornavbar="false">
  <pagenode title="users" url="~/admin/users" fornavbar="false"/>
  <pagenode title="events" url="~/admin/events" fornavbar="true"/>
 </pagenode>
 <pagenode title="catalog" url="~/catalog" fornavbar="true"/>
 <pagenode title="contact us" url="~/contactus" fornavbar="false"/>
</pagenode>

Теперь я хочу получить XML-документ для панели навигации, который включает в себя все pagenodes с fornavbar = true.как это можно сделать?

самое близкое, что я смог получить до сих пор, было это:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="pagenode[@fornavbar='true']">
  <xsl:copy-of select="."/>
 </xsl:template>
</xsl:stylesheet>

проблема с этим состоит в том, что включает в себя все дочерние элементы всего, что соответствует navbar

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

, но если я попытаюсь

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="pagenode[@fornavbar='true']">
  <pagenode title="{@title}"  url="{@url}"/>
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

, тогда у меня 2 проблемы

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

Я был бы признателен всем и за любую помощь в этом вопросе.

спасибо!

РЕДАКТИРОВАТЬ: пример выходных данных, который нравитсясм

<pagenode title="home" url="~/" fornavbar="true">
 <pagenode title="events" url="~/admin/events" fornavbar="true"/>
 <pagenode title="catalog" url="~/catalog" fornavbar="true"/>
</pagenode>

Ответы [ 3 ]

3 голосов
/ 25 января 2011

Вероятно, это самое короткое и чистое решение XSLT:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="*[@fornavbar = 'false']">
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

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

<pagenode title="home" url="~/" fornavbar="true">
    <pagenode title="admin" url="~/admin" fornavbar="false">
        <pagenode title="users" url="~/admin/users" fornavbar="false"/>
        <pagenode title="events" url="~/admin/events" fornavbar="true"/>
    </pagenode>
    <pagenode title="catalog" url="~/catalog" fornavbar="true"/>
    <pagenode title="contact us" url="~/contactus" fornavbar="false"/>
</pagenode>

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

<pagenode title="home" url="~/" fornavbar="true">
   <pagenode title="events" url="~/admin/events" fornavbar="true"/>
   <pagenode title="catalog" url="~/catalog" fornavbar="true"/>
</pagenode>

Пояснение:

  1. Правило идентификации (шаблон) копирует каждый узел "как есть". Использование правила идентификации и его переопределение является наиболее фундаментальным Шаблон проектирования XSLT.

  2. Существует один шаблон, который переопределяет правило идентификации - для элементов, атрибут fornavbar которых равен "false". Здесь указанным действием является применение шаблонов к дочерним элементам текущего элемента.

2 голосов
/ 25 января 2011

вы можете перебирать атрибуты узла, используя xsl:foreach select="@*" Таким образом, вам не нужно копировать атрибуты вручную. если вы позвоните xsl:apply-templates внутри вашего элемента pagenode вы должны получить желаемый результат.

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="pagenode[@fornavbar='true']">
        <pagenode>
            <xsl:for-each select="@*">
                <xsl:attribute name="{name(.)}"><xsl:value-of select="."/></xsl:attribute>
            </xsl:for-each>
            <xsl:apply-templates/>
        </pagenode>
    </xsl:template>
</xsl:stylesheet>

делает

<?xml version="1.0"?>
<pagenode title="home" url="~/" fornavbar="true">
    <pagenode title="events" url="~/admin/events" fornavbar="true"/>
  <pagenode title="catalog" url="~/catalog" fornavbar="true"/>
</pagenode>
1 голос
/ 25 января 2011

XSLT должен выглядеть так:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="pagenode[@fornavbar='true']">
    <pagenode>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </pagenode>
  </xsl:template>
</xsl:stylesheet>
...