【问题标题】:Get InnerText from Collection从集合中获取 InnerText
【发布时间】:2011-09-07 15:30:14
【问题描述】:

当节点在集合中时,有没有办法获取节点的内部文本 目前我有这个

Collection<string> DependentNodes = new Collection<string>();
foreach (XmlNode node in nodes)
{
  for (int i = 0; i < node.ChildNodes.Count; i++)
  {
    DependentNodes.Add(node.ChildNodes[i].InnerXml);
    //the reason i'm using InnerXml is that it will return all the child node of  testfixture in one single line,then we can find the category & check if there's dependson
   }
}
    string selectedtestcase = "abc_somewords";
    foreach (string s in DependentNodes)
     {
      if(s.Contains(selectedtestcase))
       {
        MessageBox.Show("aaa");
       }

     }

当我调试字符串 s 或索引中有这个时[在一行中]

<testfixture name="1" description="a">
  <categories>
    <category>abc_somewords</category>
  </categories>
  <test name="a" description="a">
    <dependencies>
      <dependson typename="dependsonthis" />
    </dependencies>
  </test>
</testfixture>

我想要做的是,当我们到达“testfixture 1”时,它会找到“abc_somewords”并搜索“dependson typename”节点(如果有)并获得“typename”(即“dependonthis”)。

【问题讨论】:

  • DependentNodes是什么类型?
  • 从属节点是一个集合
  • 抱歉之前没用过Linq,怎么用?
  • 如果 linq 不是你的选择,你可以试试@Jason 的回答。
  • 我现在更新了我的答案以匹配新的 xml 数据,并确保仅在类别与您的文本匹配的地方提取 typename 属性的值。

标签: c# winforms collections innertext


【解决方案1】:

假设

当您在代码中循环并想要创建一个集合时,我假设实际的 Xml 文件内部有多个 testfixture 节点,例如以下假设示例:

<root>
  <testfixture name="1" description="a">
    <categories>
      <category>abc_somewords</category>
    </categories>
    <test name="a" description="a">
      <dependencies>
        <dependson typename="dependsonthis" />
      </dependencies>
    </test>
  </testfixture>
  <testfixture name="2" description="a">
    <categories>
      <category>another_value</category>
    </categories>
    <test name="b" description="a">
      <dependencies>
        <dependson typename="secondentry" />
      </dependencies>
    </test>
  </testfixture>
  <testfixture name="3" description="a">
    <categories>
      <category>abc_somewords</category>
    </categories>
    <test name="c" description="a">
      <dependencies>
        <dependson typename="thirdentry" />
      </dependencies>
    </test>
  </testfixture>
</root>

使用 Linq to Xml 的代码

要使用 Linq,您必须引用以下名称空间:

using System.Linq;
using System.Xml.Linq;

在上面假设的 xml 文件结构上使用 Linq To Xml 如下所示:

// To Load Xml Content from File.
XDocument doc1 = XDocument.Load(@"C:\MyXml.xml");

Collection<string> DependentNodes = new Collection<string>();

var results =
    doc1.Root.Elements("testfixture")
    .Where(x => x.Element("categories").Element("category").Value.Contains("abc_somewords"))
    .Elements("test").Elements("dependencies").Elements("dependson").Attributes("typename").ToArray();

foreach (XAttribute attribute in results)
{
    DependentNodes.Add(attribute.Value.Trim());
}

结果

生成的集合将包含以下内容:

如您所见,仅提取了typename 属性的文本,其中dependson 节点在testfixture 节点中包含category 节点,其值为abc_somewords

附加说明

如果你从一个字符串中读取 xml,你也可以使用这个:

// To Load Xml Content from a string.
XDocument doc = XDocument.Parse(myXml);

如果您的完整 Xml 结构不同,请随时发布,我会更改代码以匹配。

玩得开心。

【讨论】:

  • 我现在已经更新了我的代码以匹配 xml 文件结构。我还更新了 Linq 查询以根据需要提取依赖属性 typename 值。希望现在对您有所帮助。
【解决方案2】:
using System;
using System.Xml;

namespace ConsoleApplication6
{
    class Program
    {
        private const string XML = "<testfixture name=\"1\" description=\"a\">" +
                             "<categories>" +
                             "<category>abc_somewords</category>" +
                             "</categories>" +
                             "<test name=\"a\" description=\"a\">" +
                             "<dependencies>" +
                             "<dependson typename=\"dependsonthis\" />" +
                             "</dependencies>" +
                             "</test>" +
                             "</testfixture>";

        static void Main(string[] args)
        {
            var document = new XmlDocument();
            document.LoadXml(XML);

            var testfixture = document.SelectSingleNode("//testfixture[@name = 1]");

            var category = testfixture.SelectSingleNode(".//category[contains(text(), 'abc_somewords')]");

            if(category != null)
            {
                var depends = testfixture.SelectSingleNode("//dependson");
                Console.Out.WriteLine(depends.Attributes["typename"].Value);
            }


            Console.ReadKey();
        }
    }
}

输出:依赖这个

【讨论】:

    【解决方案3】:

    由于您已经使用 XmlNode,您可以使用 XPath 表达式来选择所需的 textfixture 节点,然后选择依赖值:

    XmlDocument doc = // ...
    XmlNode node = doc.SelectSingleNode("//testfixture[contains(categories/category, \"abc\")]/test/dependencies/dependson/");
    
    if (node != null)
    {
      MessageBox.Show(node.Attributes["typename"]);
    }
    

    这将选择属于testfixture 节点的dependson 节点,其中category 包含“abc”。 node.Attributes["typename"] 将返回 typename 属性的值。

    已编辑: 将 XPath 表达式更新为更具体的问题信息

    【讨论】:

      【解决方案4】:

      我不知道您使用的是什么“节点”。

      这是符合您要求的代码(我理解的)。

      Collection<XmlNode> DependentNodes = new Collection<XmlNode>();
      
              XmlDocument xDoc = new XmlDocument();
      
              xDoc.Load(@"Path_Of_Your_xml");
      
              foreach (XmlNode node in xDoc.SelectNodes("testfixture"))  // Here I am accessing only root node. Give Xpath if ur requrement is changed
              {
                  for (int i = 0; i < node.ChildNodes.Count; i++)
                  {
                      DependentNodes.Add(node.ChildNodes[i]);
                  }
              }
              string selectedtestcase = "abc_somewords";
      
              foreach (var s in DependentNodes)
              {
                  if (s.InnerText.Contains(selectedtestcase))
                  {
                      Console.Write("aaa");
                  }
              }
      

      【讨论】:

        【解决方案5】:

        你可以使用 linq to xml。像下面这样的东西可能是一个不错的开始

        xml.Elements("categories").Where(x => x.Element("category").Value.Contains(selectedtestcase));
        

        这不是我的想法,所以可能需要改进

        附:使用 XElement.Load 或 XElement.Parse 将您的 xml 放入 XElements

        【讨论】:

        • 上面将返回父节点,所以一旦他有了这些,他就可以使用相同的技术来获取测试节点
        猜你喜欢
        • 2019-07-25
        • 2018-05-08
        • 1970-01-01
        • 2017-06-17
        • 1970-01-01
        • 2015-03-05
        • 1970-01-01
        • 1970-01-01
        • 2014-12-01
        相关资源
        最近更新 更多