如何从 XML 文件中检索多个元素

本文关键字:检索 元素 文件 XML | 更新日期: 2023-09-27 18:18:31

当我使用笨拙的叶子表资源管理器导出 TableStorage 数据时,我返回了以下 xml:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="http://x.table.core.windows.net/" 
      xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 
      xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" 
      xmlns="http://www.w3.org/2005/Atom">
    <title type="text">TestContents</title>
    <updated />
    <link rel="self" title="TestContents" href="TestContents" />
    <entry>
        <title type="text" />
        <updated />
        <author>
            <name />
        </author>
        <link rel="edit"  />
        <content type="application/xml">
            <m:properties>
                <d:PartitionKey>010100A</d:PartitionKey>
                <d:Title>ssq</d:Title>
                <d:Type>1</d:Type>
            </m:properties>
        </content>
    </entry>
    <entry>
        <title type="text" />
        <updated />
        <author>
            <name />
        </author>
        <link rel="edit"  />
        <content type="application/xml">
            <m:properties>
                <d:PartitionKey>010100B</d:PartitionKey>
                <d:Title>yy</d:Title>
                <d:Type>1</d:Type>
            </m:properties>
        </content>
    </entry>
    <entry>
        <title type="text" />
        <updated />
        <author>
            <name />
        </author>
        <link rel="edit" />
        <content type="application/xml">
            <m:properties>
                <d:PartitionKey>010100C</d:PartitionKey>
                <d:Title>xx</d:Title>
                <d:Type>1</d:Type>
            </m:properties>
        </content>
    </entry>
</feed>

我正在使用以下代码:

XNamespace a = "http://www.w3.org/2005/Atom";
XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
XNamespace m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
XElement feed = XElement.Load(@"c:'data'contents.xml");
var titles =
    from entry in feed.Descendants(a + "entry")
    let partitionKey = entry.Element(d + "PartitionKey")
    let content = entry.Element(a + "content")
    let properties = content.Element(m + "properties")
    let title = properties.Element(d + "Title")
    select title;
foreach (var title in titles)
{
    Console.WriteLine(title.Value);
}
Console.ReadLine();

从 XML 文件获取数据。 代码运行完美,为我提供了所有元素:

<d:Title>xxx</d:Title>

我现在也想获取分区键的值。为此,我修改了该行

select title:

select partitionKey, title;

但是这给了我一个错误:

"名为'title'的局部变量不能在这个作用域中声明,因为它会给'title'赋予不同的含义,'title'已经在子作用域中用于表示其他东西。

有人可以帮忙并建议我如何获取分区键的值以及控制台上的标题和显示。

如何从 XML 文件中检索多个元素

您可以使用匿名类型:

XNamespace a = "http://www.w3.org/2005/Atom";
XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
XNamespace m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
XElement feed = XElement.Load("test.xml");
var result =
    from entry in feed.Descendants(a + "entry")
    let content = entry.Element(a + "content")
    let properties = content.Element(m + "properties")
    let title = properties.Element(d + "Title")
    let partitionKey = properties.Element(d + "PartitionKey")
    select new
    {
        Title = title.Value,
        PartitionKey = partitionKey.Value,
    };
foreach (var item in result)
{
    Console.WriteLine("{0}, {1}", item.Title, item.PartitionKey);
}

或者,如果您打算将此 LINQ 查询的结果传递到当前方法之外,请先定义一个模型:

public class Result
{
    public string Result { get; set; }
    public string PartitionKey { get; set; }
}

然后将 LINQ 查询投影到IEnumerable<Result>

select new Result
{
    Title = title,
    PartitionKey = partitionKey
};

更新:

现在您已经更新了答案并显示了您正在处理的 XML,似乎 PartitionKey 是 <m:properties> 的子节点,那么您为什么要使用 let partitionKey = entry.Element(d + "PartitionKey") ?在示例中,entry表示<entry>节点。我已经更新了我以前的代码示例以匹配您的 XML。在 LINQ 查询中应更加小心/一致:

let partitionKey = properties.Element(d + "PartitionKey")
select partitionKey, title;

不做你认为它做的事情。看起来您要返回具有两个属性的匿名类型的实例:partitionKeytitle 。为此,您必须显式声明匿名类型,即

select new { partitionKey, title };

至于你的代码行实际上做了什么,根据编译器错误文本,我认为这简直是非法语法。

注意:VB.NET 编译器更宽容一些。它确实将Select partitionKey, title视为Select New With { partitionKey, title }的句法糖,这是您所期望的。