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

发布于 2024-10-01 05:46:39 字数 1139 浏览 0 评论 0原文

我正在寻找一种有效的方法来过滤 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>

我也愿意接受其他方式来做到这一点。我有一份原始文档,无法直接操作。我需要单独存储对该文档部分的“引用”。然后我需要使用“参考”来过滤/翻译原始文档以用于显示目的。

I am looking for an efficient way to filter an XML document. I am using C#/.NET. Say that I have the following original document:

<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>

I have another partial document stored somewhere else:

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

Using these two documents, I need to output the second partial XML document including its original ancestors.

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

I am also open to other ways I might be able to do this. I have an original document that I cannot manipulate directly. I need to store a "reference" to part(s) of that document separately. And then I need to filter/translate the original document using the "reference" for display purposes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青芜 2024-10-08 05:46:39

此 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 的模板决定复制当前节点(通过对其应用身份规则)仅当两个子节点(Authorcode> 和 Title) 与参考文档中的某些 Book 元素的子元素具有相同的值。

  3. 为了方便起见,我已将参考文档嵌入到 XSLT 样式表中。实际上,它将位于自己的 XML 文件中,只需稍微更改 $vReference 变量的定义即可。

This XSLT transformation:

<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>

when applied on the provided XML document:

<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>

produces the wanted, correct result:

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

Do note:

  1. The identity rule is used to copy any node "as-is", except for Book elements that do not match identical Book elements in the reference document.

  2. The template matching Book decides to copy the current node (by applying the identity rule on it) only if both children (Author and Title) have the same value as the children of some Book element from the reference document.

  3. Just for convenience I have embedded the reference document into the XSLT stylesheet. In practice it will be in its own XML file and this would only need a slight change in the definition of the $vReference variable.

遗心遗梦遗幸福 2024-10-08 05:46:39

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

我希望这会有所帮助。

Do try LINQ to XML,
http://www.hookedonlinq.com/LINQtoXML5MinuteOverview.ashx.

I hope this will help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文