Получить InnerText из коллекции - PullRequest
2 голосов
/ 03 июня 2011

Есть ли способ получить внутренний текст узла, когда узел находится внутри коллекции В настоящее время у меня есть это

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» и произведет поиск в узле «relatedon typename» (если есть) и получит «typename»"(что" зависит от этого ").

Ответы [ 5 ]

3 голосов
/ 03 июня 2011

Допущения

Поскольку вы зацикливаетесь на своем коде и хотите создать коллекцию, я предполагаю, что фактический 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;

Использование Linq To Xml в приведенной выше предполагаемой структуре файла 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());
}

Результат

Полученная коллекция будет содержать следующее:

enter image description here

Как видите, только текст атрибута typename был извлечен там, где узлы dependsonгде в узле testfixture, который содержал узел category со значением abc_somewords.

Дополнительные примечания

Если вычитать xml из строки, вы также можете использовать это:

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

Если ваша complete Xml структура отличается, не стесняйтесьопубликуйте его, и я изменю код для соответствия.

Веселитесь.

3 голосов
/ 03 июня 2011

Поскольку вы уже работаете с 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"]);
}

Это выбирает узел dependson, который принадлежитна testfixture узел с category, содержащим «abc».node.Attributes["typename"] вернет значение атрибута typename.

Отредактировано: Обновлено выражение XPath для более конкретной информации вопроса

3 голосов
/ 03 июня 2011

Не могли бы вы использовать linq to xml. Нечто подобное ниже может быть достойным началом

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

Это не в моей голове, так что, возможно, потребуется доработка

P.S. Используйте XElement.Load или XElement.Parse, чтобы получить xml в XElements

1 голос
/ 03 июня 2011
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();
        }
    }
}

Вывод: зависит от этого

1 голос
/ 03 июня 2011

Я не знаю, какие "узлы" вы используете.

Вот код с вашим требованием (что я понял).

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");
            }
        }
...