Я предлагаю использовать XPath для разбора значений. Для анализа структуры XML это будет более надежно, чем Regex.
var xml = @"
<root>
<span name=""foo"">
<span name=""bar"">
Missing Data
</span>
</span>
<span name=""foo"">
<span name=""bar"">
<span name=""detail1"">first detail</span>
<span name=""detail2"">second detail</span>
</span>
</span>
</root>
";
var document = XDocument.Parse(xml);
var details = document.XPathSelectElements("//span[@name='foo']/span[@name='bar']/span[starts-with(@name,'detail')]")
.Select(arg => arg.Value)
.ToList();
или LINQ-to-XML
var details = document
.Descendants("span").Where(arg => arg.Attribute("name").Value == "foo")
.Elements("span").Where(arg => arg.Attribute("name").Value == "bar")
.Elements("span").Where(arg => arg.Attribute("name").Value.StartsWith("detail"))
.Select(arg => arg.Value)
.ToList();
[Редактировать] Я мог бы неправильно понять вопрос. Похоже, вы также хотите заменить или заполнить некоторые значения. Вы можете сделать это с помощью вышеупомянутого подхода, если у вас есть XDocument
. Например, этот код очистит значения элементов detail1
и detail2
:
var detailNodes = document.XPathSelectElements("//span[@name='foo']/span[@name='bar']/span[starts-with(@name,'detail')]")
.ToList();
detailNodes[0].Value = string.Empty;
detailNodes[1].Value = string.Empty;
var newXml = document.ToString();
[Изменить]
Как добавить элемент:
var elementsWithMissingDetals = document
.XPathSelectElements("//span[@name='foo']/span[@name='bar' and count(*)=0]")
.ToList();
foreach (var elementsWithMissingDetal in elementsWithMissingDetals)
{
elementsWithMissingDetal.Add(
new XElement("span", "first detail", new XAttribute("name", "detail1")));
elementsWithMissingDetal.Add(
new XElement("span", "second detail", new XAttribute("name", "detail2")));
}
var newXml = document.ToString();