0

I have a List containing elements like this:

{<d:element m:type="SP.KeyValue" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
  <d:Key>Path</d:Key>
  <d:Value>https://my.home.site.com</d:Value>
  <d:ValueType>Edm.String</d:ValueType>
</d:element>}

I'd like help to discern the Linq statement required to extract only the "https://my.home.site.com" values from said List<>. The catch here is that we cannot only use the <d:Value> because only XElements in this list that has a <d:Key> value of Path, like in the example above, actually contain URLs in the <d:Value> key.

Does anyone know the magic Linq statement that would perform said data extract?

3 Answers3

2

Assuming your data is coming from an XML file similar to this:

<?xml version="1.0"?>
<root xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
    <d:element m:type="SP.KeyValue">
        <d:Key>Path</d:Key>
        <d:Value>https://my.home.site.com</d:Value>
        <d:ValueType>Edm.String</d:ValueType>
    </d:element>
    <d:element m:type="SP.KeyValue">
        <d:Key>NotPath</d:Key>
        <d:Value>https://my.home.site.com</d:Value>
        <d:ValueType>Edm.String</d:ValueType>
    </d:element>
</root>

The following code:

XElement  root = XElement.Load("Some file");
List<string> urls;

//Query Syntax
urls = (from e in root.Elements(d + "element")
        where e.Element(d + "Key").Value == "Path"
        select e.Element(d + "Value").Value);
//Or

//Method Syntax
urls = (from e in root.Elements(d + "element")
        where e.Element(d + "Key").Value == "Path"
        select e.Element(d + "Value").Value).ToList();

Console.WriteLine(string.Join(",", urls));

Will result in (note that it ignores the "NotPath" key):

https://my.home.site.com

You can check out a live example here and check out this for more XElement information.

amura.cxg
  • 2,348
  • 3
  • 21
  • 44
1

if you actually have a List of XElement:

var list = new List<XElement>(); //however you get your XElement collection

var values = list.Where(x => x.Elements().First(e => e.Name.LocalName == "Key").Value == "Path")
                 .Select(x => x.Elements().First(e => e.Name.LocalName == "Value").Value)

if you have an XDocument, you'd just modify the beginning of the query slightly.

Jonesopolis
  • 25,034
  • 12
  • 68
  • 112
0

I think that problem if with naespace declaration. Try this:

string xml = "<d:element m:type=\"SP.KeyValue\" xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\" xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\">"+
"<d:Key>Path</d:Key>"+
"<d:Value>https://my.home.site.com</d:Value>"+
"<d:ValueType>Edm.String</d:ValueType>"+
"</d:element>";

XDocument xmlObj = XDocument.Parse(xml);
XNamespace ns_d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
var result = xmlObj.Descendants(ns_d + "Value").Select(x => x.Value);
daniell89
  • 1,832
  • 16
  • 28
  • You are correct that namespaces were part of the issue... here's my code that worked, based off amura.cxg's answer: var urls = (from e in items.Elements(d + "element") where e.Element(d + "Key").Value == "Path" select e.Element(d + "Value").Value); – Cornelius J. van Dyk Mar 15 '17 at 21:24