过滤部分XML文档的有效方法

时间:2010-11-05 03:23:48

标签: c# .net xml xslt .net-3.5

我正在寻找一种过滤XML文档的有效方法。我正在使用C#/ .NET。说我有以下原始文件:

<Bookstores>
   <Bookstore>
      <StoreName>Store 1</StoreName>
      <Books>
         <Book>
            <Author>Bob</Author>
            <Title>ABC</Title>
         </Book> 
         <Book>
            <Author>John</Author>
            <Title>XYZ</Title>
         </Book> 
      </Books>
   </Bookstore>
</Bookstores>

我还有另一个部分文档存储在其他地方:

<Book>
   <Author>John</Author>
   <Title>XYZ</Title>
</Book> 

使用这两个文档,我需要输出第二个部分XML文档,包括其原始祖先。

<Bookstores>
   <Bookstore>
      <StoreName>Store 1</StoreName>
      <Books>
         <Book>
            <Author>John</Author>
            <Title>XYZ</Title>
         </Book> 
      </Books>
   </Bookstore>
</Bookstores>

我也可以采取其他方式来做到这一点。我有一份原始文件,我无法直接操纵。我需要单独存储该文档的一部分“参考”。然后我需要使用“参考”过滤/翻译原始文档以供显示。

2 个答案:

答案 0 :(得分:4)

此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:variable name="vrtfReference">
     <Book>
       <Author>John</Author>
       <Title>XYZ</Title>
     </Book>
 </xsl:variable>

 <xsl:variable name="vReference" select=
 "document('')/*/xsl:variable
                  [@name='vrtfReference']/*"/>

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

 <xsl:template match="Book">

   <xsl:apply-templates mode="copy" select=
    "self::node()[$vReference
                   [Author = current()/Author
                  and
                   Title = current()/Title
                   ]
                  ]
    "/>
 </xsl:template>

 <xsl:template match="node()" mode="copy">
  <xsl:call-template name="identity"/>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<Bookstores>
   <Bookstore>
      <StoreName>Store 1</StoreName>
      <Books>
         <Book>
            <Author>Bob</Author>
            <Title>ABC</Title>
         </Book>
         <Book>
            <Author>John</Author>
            <Title>XYZ</Title>
         </Book>
      </Books>
   </Bookstore>
</Bookstores>

生成想要的正确结果

<Bookstores>
   <Bookstore>
      <StoreName>Store 1</StoreName>
      <Books>
         <Book>
            <Author>John</Author>
            <Title>XYZ</Title>
         </Book>
      </Books>
   </Bookstore>
</Bookstores>

请注意

  1. 标识规则用于“按原样”复制任何节点,但Book元素与参考中的相同Book元素不匹配文档。

  2. 匹配Book的模板决定复制当前节点(通过在其上应用标识规则)仅当两个子项(AuthorTitle)与参考文档中某些Book元素的子元素具有相同的值。

  3. 为方便起见,我已将参考文档嵌入到XSLT样式表中。实际上它将在自己的XML文件中,这只需要对$vReference变量的定义稍作修改。

答案 1 :(得分:1)

尝试LINQ to XML, http://www.hookedonlinq.com/LINQtoXML5MinuteOverview.ashx

我希望这会有所帮助。