7

嗨,我有一个看起来像这样的站点地图 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>

现在我想检索导航栏的 xml 文档,其中包括所有具有 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>

这样做的问题是包括任何匹配为导航栏的所有子项

我只想复制所有属性,而不是所有孩子

但如果我尝试

<?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. 它失去了层次结构。一切都变得平坦

对于此事,我将不胜感激。

谢谢你!

编辑:id 喜欢看到的示例输出

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

3 回答 3

3

您可以使用这种方式迭代节点的属性,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>
于 2011-01-25T11:57:48.023 回答
3

这可能是最短和最纯粹的 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". 这里指定的操作是在当前元素的子元素上应用模板。

于 2011-01-25T14:27:41.767 回答
1

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>
于 2011-01-25T12:07:17.073 回答