在不知道xdoc的结构的情况下,选择其立即值为的元素

时间:2015-07-28 03:32:06

标签: c# linq linq-to-xml

更新: 我完全过分简化了这个问题,并将每个人误入歧途。这是实际的问题:我正在尝试获取其值与正则表达式匹配的元素。我重写了这个问题......

鉴于我不知道结构的XDocument,如何选择具有与正则表达式匹配的值的所有元素?

例如:

<html>
    <head></head>
    <body>
        <table>
            <tr>
                <td>{{ var1 }}</td>
                <td>{{ var2 }}</td>
            </tr>
            <tr>
                <td>{{ var3 }}</td>
                <td>{{ var4 }}</td>
            </tr>
        </table>
    </body>
</html>

我会得到html,body,table,tr和四个td元素的结果。如何选择具有与此正则表达式匹配的值的所有元素,并仅返回td元素

private Regex _placeholderRegex = new Regex("({{.+?}})");

public string GetParsedDocument(...)
{
    var placeHolders = _template
        .Descendants()
        .Where(d => _placeholderRegex.IsMatch(d.Value));

    // more stuff
    return null;
}

我最终得到的结果是每个元素都是我正在寻找的元素的祖先......

所以现在我考虑一下,我看到它只是查看每个元素的全部内容并选择它,如果它包含任何地方的匹配。所以我想只需找到一种缩小范围的方法。

3 个答案:

答案 0 :(得分:0)

这是一种可能的方式:

var placeHolders = from d in mydoc.Descendants()
                   where d.DescendantNodes()
                          .OfType<XText>()
                          .Any(o => o.Parent == d && _placeholderRegex.IsMatch(o.Value))
                   select d;

上述代码的工作原理是检查任何文本节点(即当前节点dParent == d)的直接子节点)是否具有与正则表达式模式匹配的值。

以下是demo的一个工作示例:

var xml = @"<html>
    <head></head>
    <body>
        <table>
            <tr>
                <td>{{ var1 }}</td>
                <td>{{ var2 }}</td>
            </tr>
            <tr>
                <td>{{ var3 }}</td>
                <td>{{ var4 }}</td>
            </tr>
        </table>
    </body>
</html>";
var mydoc = XDocument.Parse(xml);
var _placeholderRegex = new Regex("({{.+?}})");
var placeHolders = from d in mydoc.Descendants()
                   where d.DescendantNodes()
                          .OfType<XText>()
                          .Any(o => o.Parent == d && _placeholderRegex.IsMatch(o.Value))
                   select d;
foreach (var placeHolder in placeHolders)
{
    Console.WriteLine(placeHolder.Value);
}

输出

{{ var1 }}
{{ var2 }}
{{ var3 }}
{{ var4 }}

答案 1 :(得分:0)

如果我理解正确的话:

  1. 如果只有td元素,请替换.Descendants(“td”)上的.Descendants()

    var placeHolders = mydoc
                .Descendants()
                .Where(d => !d.HasElements && _placeholderRegex.IsMatch((string)d))
                .Select(x => (string)x);
    
  2. 链接:https://dotnetfiddle.net/eoDVWH

    1. 或者,检查子元素是否存在:

      < =
    2. 链接:https://dotnetfiddle.net/FEwSf3

答案 2 :(得分:0)

您可以在谓词中添加!d.Elements().Any(),以便只获取没有孩子的元素:

var placeHolders = _template
    .Descendants()
    .Where(d => !d.Elements().Any() && _placeholderRegex.IsMatch((string)d))
    .ToList();