如何根据 xml 列表是否具有特定属性来过滤它

How to filter an xml list based on whether it has a particular attribute

几个小时以来,我一直在努力思考一些事情。

我正在编写一个应用程序,它将从 word 文档中删除评论并将它们写在另一个文档的 table 中以供审计。作为一项要求,它需要包含对评论来源的行引用,如果是回复,则需要包含对 parent 评论的引用。

我已经使用 DocumentFormat.OpenXml 库从 word 文档中找到了所有 3 个文档部分。但是,我在尝试获取回复评论时卡住了。

包含对评论及其 parent 的引用的 XML 如下

<w15:commentsEx xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se wp14">
  <w15:commentEx w15:paraId="739FE385" w15:done="0" />
  <w15:commentEx w15:paraId="64E7F09D" w15:done="0" />
  <w15:commentEx w15:paraId="04DC26C3" w15:done="0" />
  <w15:commentEx w15:paraId="55A4D8B0" w15:paraIdParent="04DC26C3" w15:done="0" />
</w15:commentsEx>

现在我认为我的问题是因为它们都有名称空间,所以我必须使用 where 子句来获取属性的本地名称。例如

CommentsEx.Descendants().Where(x => x.Name.LocalName == "commentEx")

我有一个 MyComment 类型的列表,其中包含评论文本、作者、xmlId(xml 中的 paraId)和对其 parent 的引用(paraIdParent 在xml),我现在想获得所有具有 parent 的评论的列表。我尝试获取 commentEx 列表,然后调用以下 linq 语句

var replyComments = comment.Attributes()
                .Where(x => x.Name.LocalName == "paraIdParent").ToList();

但那只是 returns 属性本身的列表,而不是包含该属性的 commentEx 的列表。

如果我试图只获取属性的值,它会导致它崩溃,因为该属性并不存在于所有标签上。

所以我总结了一下。我需要遍历 commentsEx 并查找具有 parents 的评论。然后我需要使用属性 paraId 从我的列表中获取正确的注释,以便能够使用 paraIdParent 将 link 添加到 parent。但我无法让它工作。我使用了错误的工具吗?我不应该使用 linq 吗?

我想 LINQ-to-XML 会使您的任务变得容易得多。您可以指定 w15 的名称空间以及节点名称。您可以为此使用 XNamespace class:-

XDocument xdoc = XDocument.Load(@"YourXMLPath");
XNamespace ns = "http://schemas.microsoft.com/office/word/2012/wordml";
IEnumerable<XElement> replyComments = xdoc.Root.Elements(ns + "commentEx")
                    .Where(x => (string)x.Attribute(ns + "paraIdParent") != null);

更新:

您可以只检查 null,因为如果找不到属性,(string)x.Attribute(ns + "paraIdParent") 将 return null

尝试这样的事情:

var replyComments = (from comment in CommentsEx.Descendants()
                    where comment.Name.LocalName == "commentEx"
                    from attrib in comment.Attributes()
                    where attrib.Name.LocalName == "paraIdParent"
                    select comment).ToList();