условные задачи регулярного выражения в C # - PullRequest
2 голосов
/ 11 июня 2011

У меня есть контент, вложенный в теги span. У некоторых из них есть детали, которые мне нужно вытащить, а у некоторых нет. Я не могу понять, как проверить два варианта и получить правильные данные. Эти группы повторяются. Например:

<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>

Мне нужно захватить детали по отдельности, если они есть, в противном случае мне нужно установить значения null в строках в моей программе при циклическом просмотре matchcollection, поэтому мой код должен установить strDetail1 и strDetail2 в "" или значения «первая деталь» и «вторая деталь», если это имеет смысл.

1 Ответ

2 голосов
/ 11 июня 2011

Я предлагаю использовать 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();
...