首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT删除不在列表中的节点,同时保留列表中的任何子节点。

XSLT删除不在列表中的节点,同时保留列表中的任何子节点。
EN

Stack Overflow用户
提问于 2013-05-01 22:42:19
回答 1查看 279关注 0票数 1

我有一个I列表,我想使用这些I来“筛选”所提供的xml文件。应该保留列表中的每个节点,删除列表中的每个节点。

对我来说,困难在于当我删除一个节点(而不是在IDList中)时,我还会删除可能在IDList中的一个子节点。

最后,我需要保留节点的嵌套(参见下面的示例)。

这是我的ID列表:

IDList = 2,3,5,6

这是我输入的xml是:

<联想ASSOCIATION_ID="1">榆木协会<协会ASSOCIATION_ID="2">橡木协会<协会ASSOCIATION_ID="4">橡木子协会A<协会ASSOCIATION_ID="6">橡木子协会<协会_ID="5">橡木子协会B<协会ASSOCIATION_ID="3">杉木协会

这是我想要的输出:

<关联ASSOCIATION_ID="2">橡木协会<关联ASSOCIATION_ID="6">橡木子协会<关联ASSOCIATION_ID="5">橡木子协会B<协会ASSOCIATION_ID="3">杉木协会

任何帮助都将不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-02 02:14:10

XSLT2.0解决方案:I.

代码语言:javascript
复制
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pIds" select="2, 3, 5, 6" as="xs:integer+"/>

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

 <xsl:template priority="2" match=
  "Association[not(@ASSOCIATION_ID = $pIds)
             and not(.//Association[@ASSOCIATION_ID = $pIds])]"/>

 <xsl:template match=
  "Association[@ASSOCIATION_ID = $pIds]
        //Association[not(@ASSOCIATION_ID = $pIds)]
  |
   *[not(self::Association[@ASSOCIATION_ID = $pIds])]
      /node()[not(descendant-or-self::Association[@ASSOCIATION_ID = $pIds])]
  ">
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

应用于所提供的XML文档时:

代码语言:javascript
复制
<Associations>
    <Association ASSOCIATION_ID="1">
        Elmwood Association
        <Homes/>
    </Association>
    <Association ASSOCIATION_ID="2">
        Oakwood Association
        <Homes/>
        <Association ASSOCIATION_ID="4">
            Oakwood Sub Association A
            <Homes/>
            <Association ASSOCIATION_ID="6">
                Oakwood Sub Sub Association
                <Homes/>
            </Association>
        </Association>
        <Association ASSOCIATION_ID="5">
            Oakwood Sub Association B
            <Homes/>
        </Association>
    </Association>
    <Association ASSOCIATION_ID="3">
        Cedarwood Association
        <Homes/>
    </Association>
</Associations>

生成想要的、正确的结果

代码语言:javascript
复制
<Associations>
   <Association ASSOCIATION_ID="2">
        Oakwood Association
        <Homes/>
      <Association ASSOCIATION_ID="6">
                Oakwood Sub Sub Association
                <Homes/>
      </Association>
      <Association ASSOCIATION_ID="5">
            Oakwood Sub Association B
            <Homes/>
      </Association>
   </Association>
   <Association ASSOCIATION_ID="3">
        Cedarwood Association
        <Homes/>
   </Association>
</Associations>

II. XSLT1.0解决方案:

代码语言:javascript
复制
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <my:ids>
   <id>2</id>
   <id>3</id>
   <id>5</id>
   <id>6</id>
 </my:ids>

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

 <xsl:template priority="2" match=
  "Association[not(@ASSOCIATION_ID = document('')/*/my:ids/*)
             and not(.//Association[@ASSOCIATION_ID = document('')/*/my:ids/*])]"/>

 <xsl:template match=
  "Association[@ASSOCIATION_ID = document('')/*/my:ids/*]
        //Association[not(@ASSOCIATION_ID = document('')/*/my:ids/*)]
  |
   *[not(self::Association[@ASSOCIATION_ID = document('')/*/my:ids/*])]
      /node()[not(descendant-or-self::Association
                         [@ASSOCIATION_ID = document('')/*/my:ids/*])]
  ">
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16327650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档