C# 如何计算XML中具有相同innertext值的节点数

C# 如何计算XML中具有相同innertext值的节点数,c#,asp.net,xml,C#,Asp.net,Xml,我正在写一个C代码。我的XML文档具有不同的节点,其中我需要计算具有相同innertext值的节点数。我正在使用XmlDocument。假设我有一个xml文件,其中必须计算具有InnerText值BSS的节点数 代码: BSS 猫 BSS 基础知识 BSS PCT 在上面的代码中,我想计算具有innertext值BSS的节点数。就像这里的计数应该是3。非常感谢您的帮助 编辑代码: <Annotations> <Objects> <ObjectId>B

我正在写一个C代码。我的XML文档具有不同的节点,其中我需要计算具有相同innertext值的节点数。我正在使用XmlDocument。假设我有一个xml文件,其中必须计算具有InnerText值BSS的节点数

代码:


BSS
猫
BSS
基础知识
BSS
PCT
在上面的代码中,我想计算具有innertext值BSS的节点数。就像这里的计数应该是3。非常感谢您的帮助

编辑代码:

<Annotations>
 <Objects>
  <ObjectId>BSS|SAF|PAT</ObjectId>
  <ObjectId>CAT</ObjectId>
 </Objects>
<Objects>
  <ObjectId>BSS|SAF|PAT</ObjectId>
  <ObjectId>ABC</ObjectId>
 </Objects>
<Objects>
  <ObjectId>BSS|SAF|PAT</ObjectId>
  <ObjectId>PCT</ObjectId>
 </Objects>
</Annotations>

BSS | SAF | PAT
猫
BSS | SAF | PAT
基础知识
BSS | SAF | PAT
PCT

我将使用新的
Linq to XML
api:

var xDocument = XDocument.Load("path");

int count = xDocument.Descendants().Count(x => (string)x == "BSS");

我将使用新的
linqtoxml
api:

var xDocument = XDocument.Load("path");

int count = xDocument.Descendants().Count(x => (string)x == "BSS");

如果将其作为
XmlDocument
加载,则可以执行以下操作

doc.selectNodes("//*[.='BSS']").Count;
doc.selectNodes("Annotations/Objects/ObjectId[.='BSS']").Count;
尽管我认为可能有一种更有效的方法来编写XPath,但匹配所有内容然后检查其文本内容感觉可能效率低下

如果这是一份完整且具有代表性的文件,那么您可以这样做

doc.selectNodes("//*[.='BSS']").Count;
doc.selectNodes("Annotations/Objects/ObjectId[.='BSS']").Count;
这将更加有效,因为它针对的是特定的元素,而不是整个文档

如果搜索文本包含在管道(
|
)分隔列表中,则可以使用此谓词而不是
[.='BSS']

[contains(concat('|',.,'|'),'|BSS|')]

虽然这会比较慢。就个人而言,我建议无论您的源代码来自何处,都对其进行修改以将此列表分隔为单独的元素,这将使查询您的数据变得更加容易。我强烈主张XML文档应遵循与数据库的“第一范式”规则相同的原则,并且在任何一个文本节点/属性中不包含多个值。

如果将其作为
XmlDocument
加载,您可以这样做

doc.selectNodes("//*[.='BSS']").Count;
doc.selectNodes("Annotations/Objects/ObjectId[.='BSS']").Count;
尽管我认为可能有一种更有效的方法来编写XPath,但匹配所有内容然后检查其文本内容感觉可能效率低下

如果这是一份完整且具有代表性的文件,那么您可以这样做

doc.selectNodes("//*[.='BSS']").Count;
doc.selectNodes("Annotations/Objects/ObjectId[.='BSS']").Count;
这将更加有效,因为它针对的是特定的元素,而不是整个文档

如果搜索文本包含在管道(
|
)分隔列表中,则可以使用此谓词而不是
[.='BSS']

[contains(concat('|',.,'|'),'|BSS|')]

虽然这会比较慢。就个人而言,我建议无论您的源代码来自何处,都对其进行修改以将此列表分隔为单独的元素,这将使查询您的数据变得更加容易。我强烈主张XML文档应遵循与数据库“第一范式”规则相同的原则,并且在任何一个文本节点/属性中不包含多个值。

这不太可能有帮助,OP要求搜索内部文本与特定值匹配的节点,不是标记名。这不太可能有帮助,OP要求搜索内部文本与特定值匹配的节点,而不是标记名。感谢您的帮助!!然而,如果有任何使用XmlDocument的解决方案,这将是一个很大的帮助。在我当前的项目中,我使用的是Xmldocument,不能使用LINQtoXML…谢谢你的帮助!!然而,如果有任何使用XmlDocument的解决方案,这将是一个很大的帮助。在我当前的项目中,我使用的是Xmldocument,不能使用Linq to XML…请告诉我是否有任何有效的方法通过匹配整个路径来编写代码。谢谢Flynn,这对我很有效。然而,我需要知道我是否有一个不同的场景,在管道或逗号分隔的单个节点中有2或3个内部文本值。那么如何获得相同BSS值的计数。请查看已编辑的代码。请告诉我是否有任何有效的方法通过匹配整个路径来编写代码。谢谢Flynn,这对我很有效。然而,我需要知道我是否有一个不同的场景,在管道或逗号分隔的单个节点中有2或3个内部文本值。那么如何获得相同BSS值的计数。请查看编辑后的代码。