简体   繁体   中英

How can I retrieve multiple elements from an XML file

I have the following xml that's returned when I do an export of TableStorage data using the Clumsy Leaf Table explorer:

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

I am using the following code:

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();

To get data from an XML file. The code works perfectly and gives me the value of all the elements:

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

I would now like to get the value of the partitionKey also. To do this I modified the line

select title:

to

select partitionKey, title;

However this gives me an error:

"A local variable named 'title' cannot be declared in this scope because it would give a different meaning to 'title' which is already used in a child scope to denote something else.

Can someone help and suggest how I could also get the values for partitionKey as well as title and display on the console.

You could use an anonymous type:

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);
}

or if you intend to pass the result of this LINQ query outside of the current method start by defining a model:

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

and then project the LINQ query to an IEnumerable<Result> :

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

UPDATE:

Now that you have updated your answer and shown the XML you are dealing with it seems that PartitionKey is a subnode of <m:properties> , so why are you using let partitionKey = entry.Element(d + "PartitionKey") ? In example entry represents the <entry> node. I have updated my previous code sample to match your XML. You should be more careful/consistent in your LINQ queries:

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

does not do what you think it does. It looks like you want to return instances of an anonymous type with two properties: partitionKey and title . To do this, you must declare the anonymous type explicitly, ie

select new { partitionKey, title };

As to what your line of code actually does, based on the compiler error text, I think that it is simply illegal syntax.

NB: The VB.NET compiler is a bit more forgiving. It does treat Select partitionKey, title as syntactic sugar for Select New With { partitionKey, title } , which is what you would expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM