Linq to XML Get the next node of the same name
Here is my XML
<assets>
<asset>
<metadata Id="ItemType" Value="Image"/>
<metadata Id="ItemUri" Value="http://blah.png"/>
</asset>
<asset>
<metadata Id="ItemType" Value="Image"/>
<metadata Id="ItemUri" Value="http://blah2.png"/>
</asset>
</assets>
How do I get the 2nd <metadata>
's value containing the URI?
List<Asset> assets = (from asset in xmlDocument.Descendants("asset")
select new Asset
{
ItemType = asset.Element("metadata").Attribute("Value").Value,
开发者_StackOverflow ItemUri = asset.Element("metadata").Attribute("Value").Value
}).ToList<Asset>();
Currently my code just returns the same value from the first <metadata>
of course.
This is what I ended up doing. The answers above where good but if the <metadata>
s are not in order then I'll get the wrong data. This way I do a query and get the correct one no matter the order.
List<Asset> assets = (from asset in xmlDocument.Descendants("asset")
select new Asset
{
ItemType = asset.Elements().Single(x => x.Attribute("Id").Value == "ItemType").Attribute("Value").Value,
ItemUri = asset.Elements().Single(x => x.Attribute("Id").Value == "ItemUri").Attribute("Value").Value,
}).ToList<Asset>();
Seems that .Element(..) gets the first element with matching name if multiple elements are present. You can edit the linq query to something like
var assets = (from asset in doc.Descendants("asset")
let metadata = asset.Descendants("metadata").ToArray()
let type = metadata[0].Attribute("Value").Value
let uri = metadata[1].Attribute("Value").Value
select new Asset { ItemType = type, ItemUri = uri }).ToList();
var assets = (from asset in xmlDocument.Descendants("asset")
select new Asset
{
ItemType = (string)asset.Element("metadata").Attribute("Value"),
ItemUri = (string)asset.Elements("metadata").ElementAt(1).Attribute("Value")
}).ToList();
This code will give you an IEnumerable
of some anonymous type, but you already know how to turn it into the right type.
var assets = from asset in xd.Descendants("asset")
from metaType in asset.Descendants("metadata")
from metaUri in asset.Descendants("metadata")
where metaType.Attribute("Id").Value == "ItemType"
&& metaUri.Attribute("Id").Value == "ItemUri"
select new
{
ItemType = metaType.Attribute("Value").Value,
ItemUri = metaUri.Attribute("Value").Value
};
精彩评论