XElement 上的 XPath 列表

Posted

技术标签:

【中文标题】XElement 上的 XPath 列表【英文标题】:List of XPaths on XElement 【发布时间】:2020-07-07 09:21:54 【问题描述】:

我正在尝试在我的 C# 中获取第一个 xpath 匹配的值 -

private string getValue(List<string> xpaths, XElement xml) 
        string stringValue = string.Empty;
        foreach(string xpath in xPaths)
        
            var value = xml.XPathEvaluate(xpath);

            if (value is IEnumerable)
            
                foreach (XObject xObject in value)
                
                    if (xObject is XElement)
                    
                        stringValue = ((XElement)xObject).Value.FirstOrDefault().ToString();
                        break;
                    
                    else if (xObject is XAttribute)
                    
                        stringValue = ((XAttribute)xObject).Value.FirstOrDefault().ToString();
                        break;
                    
                
            
            else
                stringValue = value.ToString();
        
        return stringValue;


我的列表将如下所示 -

//Request/Header/Error/text()    
//Request/Header/Error[0]/Details/ErrorMesage/text()
//Request/Header/Error/Details/@code
//Request/Header/Error/Details/StackTrace/text()

在 XPath 列表中,我想遍历列表并返回第一个匹配项。 XPathEvaluate 对我不起作用。我不确定出了什么问题。

可能的 XML 值

<Request>
  <Header>
    <Error>
        <Details>
            <StackTrace>trace</StackTrace>
        </Details>
    <Error>
  </Header>
</Request>


 <Request>
  <Header>
    <Error>
        <Details>
            <ErrorMessage>This is the Error Message1.</ErrorMessage>
        </Details>
    <Error>
    <Error>
        <Details>
            <ErrorMessage>This is the Error Message2.</ErrorMessage>
        </Details>
    <Error>
  </Header>
</Request>

<Request>
  <Header>
    <Error>This is the error message.<Error>
  </Header>
</Request>

<Request>
  <Header>
    <Error>
        <Details code="123">
            <StackTrace>trace</StackTrace>
        </Details>
    <Error>
  </Header>
</Request>

<Request>
  <Header>
    <Error>
        <Details>
            <ErrorMessage>This is the Error Message.</ErrorMessage>
        </Details>
    <Error>
  </Header>
</Request>

这是传递给这样的方法-

getValue(xpathList, XElement.Parse(xmlString))

因为我不知道我会得到什么 xml,所以我想循环浏览 XPath 列表并返回第一个匹配项。它可以是元素文本或属性值。

【问题讨论】:

你能分享xml和调用getValue的函数吗?为什么XElement xml 用作参数而不使用? @Sajid 对不起,我更新了函数以使用传入的 xml。XElement 是具有请求对象的 xml @Sajid 我也添加了一些例子 我测试了我的答案,它工作正常,抱歉回答迟了 【参考方案1】:

首先,我们使用XDocument,你可以使用XElement但是你需要为xpathList更改XPath表达式, more details: 1 - 您在所有xml 测试用例中都有错误,Error 标签未关闭,然后更正它们:

<Request>
  <Header>
    <Error>
        <Details>
            <StackTrace>trace</StackTrace>
        </Details>
    </Error>
  </Header>
</Request>

2 - 你在这个表达式中有一个错误//Request/Header/Error[0]/Details/ErrorMesage/text(), 要获得第一个Error,请使用1 而不是0,您还错过ErrorMesage 中的s

List<string> xPathList = new List<string>

    "//Request/Header/Error/text()",
    "//Request/Header/Error[1]/Details/ErrorMessage/text()",
    "//Request/Header/Error/Details/@code",
    "//Request/Header/Error/Details/StackTrace/text()"
;

3 - 更改GetValue,如下代码:

private string GetValue(List<string> xPaths, XDocument xml)

    string stringValue = string.Empty;
    foreach (string xpath in xPaths)
    
        var value = xml.XPathEvaluate(xpath);

        foreach (XObject xObject in (IEnumerable)value)
        
            if (xObject is XElement)
            
                return ((XElement)xObject).Value;
            
            else if (xObject is XAttribute)
            
                return ((XAttribute)xObject).Value;
            
            else
            
                return ((XText)xObject).Value;
            
        
    

    return stringValue;

4 - 测试

string result = GetValue(xPathList, XDocument.Parse(xmlString));

5 - 演示

 string xml1 = @"<Request>
                <Header>
                    <Error>
                        <Details>
                            <StackTrace>trace</StackTrace>
                        </Details>
                    </Error>
                  </Header>
            </Request>";

string xml2 = @"<Request>
                  <Header>
                    <Error>
                        <Details>
                            <ErrorMessage>This is the Error Message1.</ErrorMessage>
                        </Details>
                    </Error>
                    <Error>
                        <Details>
                            <ErrorMessage>This is the Error Message2.</ErrorMessage>
                        </Details>
                    </Error>
                  </Header>
                </Request>";

string xml3 = @"<Request>
                  <Header>
                    <Error>This is the error message.</Error>
                  </Header>
                </Request>";

string xml4 = @"<Request>
                  <Header>
                    <Error>
                        <Details code=""123"">
                            <StackTrace>trace</StackTrace>
                        </Details>
                    </Error>
                  </Header>
                </Request>";

string xml5 = @"<Request>
          <Header>
            <Error>
                <Details>
                    <ErrorMessage>This is the Error Message.</ErrorMessage>
                </Details>
            </Error>
          </Header>
        </Request>";

List<string> xPathList = new List<string>

    "//Request/Header/Error/text()",
    "//Request/Header/Error[1]/Details/ErrorMessage/text()",
    "//Request/Header/Error/Details/@code",
    "//Request/Header/Error/Details/StackTrace/text()"
;

string result1 = GetValue(xPathList, XDocument.Parse(xml1));
Console.WriteLine($"xml1 : result1");

string result2 = GetValue(xPathList, XDocument.Parse(xml2));
Console.WriteLine($"xml2 : result2");

string result3 = GetValue(xPathList, XDocument.Parse(xml3));
Console.WriteLine($"xml3 : result3");

string result4 = GetValue(xPathList, XDocument.Parse(xml4));
Console.WriteLine($"xml4 : result4");

string result5 = GetValue(xPathList, XDocument.Parse(xml5));
Console.WriteLine($"xml5 : result5");

6 - 结果

xml1 : trace
xml2 : This is the Error Message1.
xml3 : This is the error message.
xml4 : 123
xml5 : This is the Error Message.

希望对你有帮助

【讨论】:

以上是关于XElement 上的 XPath 列表的主要内容,如果未能解决你的问题,请参考以下文章

子 XElement 的索引

在解析期间设置命名空间

通过xpath 1.0分别选择子元素elem

xElement Linq 创建列表

将部分 XML 字符串解析为 XElement 列表

将 Xpath 转换为列表变量并使用 For 循环