Получить InnerText из коллекции
Есть ли способ получить внутренний текст узла, когда узел находится внутри коллекции В настоящее время у меня есть это
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" и выполнит поиск в узле "depenon typename" (если есть) и получит "typename"(что означает "зависимость от этого").
5 ответов
Не могли бы вы использовать LINQ для XML. Нечто подобное ниже может быть достойным началом
xml.Elements("categories").Where(x => x.Element("category").Value.Contains(selectedtestcase));
Это не в моей голове, так что, возможно, потребуется доработка
PS Используйте XElement.Load или XElement.Parse, чтобы получить ваш XML в XElements
Поскольку вы уже работаете с 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 для более конкретной информации о вопросе.
Предположения
Поскольку вы зацикливаетесь на своем коде и хотите создать коллекцию, я предполагаю, что фактический 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());
}
Результат
Полученная коллекция будет содержать следующее:
Как видите, только текст typename
атрибут был извлечен, где dependson
узлы, где в testfixture
узел, который содержал category
узел со значением abc_somewords
,
Дополнительные примечания
Если вы читаете XML из строки, вы также можете использовать это:
// To Load Xml Content from a string.
XDocument doc = XDocument.Parse(myXml);
Если ваша полная структура XML отличается, не стесняйтесь размещать ее, и я изменяю код для соответствия.
Повеселись.
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();
}
}
}
Вывод: зависит от этого
Я не знаю, какие "узлы" вы используете.
Вот код с вашим требованием (что я понял).
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");
}
}