I am working with sharePoint Lists webservice, in order to load a dropdown in search page I need to extract all the "ows_Country" name from XML, returend in XMLNode in the Format of :
<rs:data ItemCount="1" xmlns:rs="urn:schemas-microsoft-com:rowset">
<z:row ows_Title="Nike" ows_ID="1" ows_Country="Spain" xmlns:z="#RowsetSchema" />
<z:row ows_Title="Addidas" ows_ID="4" ows_Country="Brazil" xmlns:z="#RowsetSchema" />
<z:row ows_Title="Puma" ows_ID="5" ows_Country="Spain" xmlns:z="#RowsetSchema" />
</rs:data>
I need to use LINQ to get the distinct "ows_Country" from the XMLNode, Kindly help is probably my first experience with LINQ as well as XML.
XNamespace rs = "urn:schemas-microsoft-com:rowset";
XNamespace z = "#RowsetSchema";
XDocument doc = XDocument.Load(...);
var result = doc.Element(rs + "data")
.Elements(z + "row")
.Select(e => (string)e.Attribute("ows_Country"))
.Distinct()
.ToList();
Related
Is there a way we can sort xmlnodes based on attribute values? The point is that every child node has a different name, despite it, I want to sort them by attribute.
E.g.
<Doc>
<mar_03 data="03">
<Mattina_Turno_1 />
</mar_03>
<dom_01 data="01">
<Mattina_Turno_1 />
</dom_01>
<mer_04 data="04">
<Mattina_Turno_1 />
<Mattina_Turno_2 />
</mer_04>
</Doc>
Should become
<Doc>
<dom_01 data="01">
<Mattina_Turno_1 />
</dom_01>
<mar_03 data="03">
<Mattina_Turno_1 />
</mar_03>
<mer_04 data="04">
<Mattina_Turno_1 />
<Mattina_Turno_2 />
</mer_04> </Doc>
How can I do it? After sorting obviously I want to overwrite the file.
This answer does not fix my problem since i can not define the node "item" since every my nodes are named differently.
Thanks, and please do not mark it as duplicate, because it is not!
Please try,
XDocument xdoc = XDocument.Load("File.xml");
var result = xdoc.Element("Doc")
.Elements()
.OrderBy(s => (int)s.Attribute("data"));
string xmlOutPut = string.Empty;
result.ToList().ForEach(a =>
{
xmlOutPut += a;
});
Where data and Doc is the parent element is your attribute according to your example. File.xml is your xml file name. You will get the sorted output in 'xmlOutPut'
or everything in a single Linq query,
XDocument xdoc = XDocument.Load("XMLFile2.xml");
string xmlOutPut = string.Empty;
xdoc.Element("Doc")
.Elements()
.OrderBy(s => (int)s.Attribute("data"))
.ToList().ForEach(a =>
{
xmlOutPut += a;
});
Sorting
XDocument xDoc = XDocument.Load("FileName.xml");
var res = xDoc.Element("Doc")
.Elements()
.OrderByDescending(c => (int) c.Attribute("data"));
Then to save it:
XDocument doc = new XDocument(new XElement("Doc", res));
doc.Save("FileName.xml");
I am struggling to read this xml file in linq to xml. Can someone help me here.
I need to read each track information.
<playlist version="1" xmlns="http://xspf.org/ns/0/" xmlns:jwplayer="http://developer.longtailvideo.com/trac/wiki/FlashFormats">
<title>Some title here</title>
<creator>Some creater</creator>
<info>somesite.com</info>
<trackList>
<track>
<title>Title 1</title>
<creator>Creater 1</creator>
<location>location 1</location>
</track>
<track>
<title>Title 2</title>
<creator>Creater 2</creator>
<location>location 2</location>
</track>
</trackList>
</playlist>
This is what I am trying to do.
XElement xelement1 = XElement.Load(#"pathtoxmlfile\my.xml");
IEnumerable<XElement> tracks= xelement1.Elements();
// Read the entire XML
foreach (var track in tracks.Descendants("track"))
{
Console.WriteLine(track );
Console.ReadLine();
}
I am using C#.
Thanks
Parminder
Why do you load your document into XElement instead of XDocument?
You have to use XNamespace instance within your query because your document uses default namespace xmlns="http://xspf.org/ns/0/".
var ns = XNamespace.Get("http://xspf.org/ns/0/");
You can use LINQ query to get a collection with your data extracted from XML document. Then you can iterate over that collection and do whatever you need.
var tracks = (from t in xDoc.Root.Element(ns + "trackList").Elements(ns + "track")
select new
{
Title = (string)t.Element(ns + "title"),
Creator = (string)t.Element(ns + "creator"),
Location = (string)t.Element(ns + "location")
}).ToList();
tracks will be a List<T> where T is anonymous type with 3 string properties: Title, Creator and Location.
You forget to include namespace name, do the following changes:
XNamespace defNs = "http://xspf.org/ns/0/";
And
foreach (var track in tracks.Descendants(defNs + "track"))
XElement tracks = XElement.Load(#"pathtoxmlfile\my.xml");
foreach (var track in tracks.Descendants("track"))
{
Console.WriteLine((string)track.Element("title"));
Console.WriteLine((string)track.Element("creator"));
Console.WriteLine((string)track.Element("location"));
}
I've been coding a program that stores employee data using XDocument:
<!-- School Employee Data -->
<SchoolData storeName="mikveIsrael" location="mikve">
<employee id="1">
<personalInfo>
<name>Ilan Berlinbluv</name>
<zip>58505</zip>
</personalInfo>
<employeeInfo>
<salary>5000</salary>
<id>1</id>
</employeeInfo>
</employee>
<employee id="2">...</employee>
</SchoolData>
I want my program to read every employee id attrib, but I don't know how to do so. Instead, I tried doing this:
var ids = from idz in doc.Descendants("SchoolData")
select new
{
id1 = idz.Element("employee").Attribute("id").Value
};
where doc is the XDocument var. It returns just the first one, but I want it to return an array or List<string>, I just don't know how to iterate through all the same-named employee elements.
XDocument doc = XDocument.Parse(xml);
List<string> ids = doc.Descendants("employee")
.Select(e => e.Attribute("id").Value)
.ToList();
This may helps:
var xDoc = XDocument.Load(path);
var result = xDoc.Descendants("employee")
.SelectMany(i => i.Attribute("id").Value)
.ToList();
I'm pulling an XML list of SharePoint site collection users and then trying to query the InnerXml. The InnerXml looks like this:
<Users xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/">
<User ID="91" Name="Jane Smith" LoginName="domain1\jsmith" />
<User ID="814" Name="Brad Jones" LoginName="domain1\bjones" />
<User ID="1252" Name="Charles Johnson" LoginName="domain2\cjohnson" />
</Users>
Query is not returning anything (el is null), even though there is a user with ID 814.
XmlNode siteUsers = tempug.GetUserCollectionFromSite();
XElement root = XElement.Parse(siteUsers.InnerXml);
IEnumerable<XElement> siteUsersElement =
from el in root.Elements("User")
where (string)el.Attribute("ID") == "814"
select el;
foreach (XElement el in siteUsersElement)
Console.WriteLine("el: " + el);
root contains the InnerXml text, so I don't think the problem has anything to do with SharePoint.
You're not specifying the namespace in your Elements call. Fortunately this is easy in LINQ to XML:
XNamespace ns = "http://schemas.microsoft.com/sharepoint/soap/directory/";
...
from el in root.Elements(ns + "User");
If you know that the ID attribute will always be an integer, I'd actually make that clear, and also avoid using a query expression when it doesn't help you:
// TODO: Find a nicer way of doing this; you shouldn't need to parse it again
XElement root = XElement.Parse(siteUsers.InnerXml);
var siteUserElements = root.Elements(ns + "User")
.Where(el => (int) el.Attribute("ID") == 814);
foreach (XElement el in siteUserElements)
{
Console.WriteLine("el: " + el);
}
I have such XML structure which was returned by SharePoint web services.
<rs:data ItemCount="4" xmlns:rs="urn:company:rowset">
<z:row ows_AssetId="HP010336520" />
<z:row ows_AssetId="HP010336519" />
<z:row ows_AssetId="HP010354403" />
<z:row ows_AssetId="HP010357062" />
</rs:data>
private static void Parser(List<XmlNode> data)
{
List<XmlNodeList> rows = (from row in data.AsEnumerable()
select row.SelectNodes("data/row")).ToList();
}
I was trying to query for a row, but no luck. Could you guys please help me?
You need to use an XmlNamespaceManager when querying the node list. Not seen in your code is the declaration of the 'z' namespace in the document's root: xmlns:z="#RowsetSchema".
Try the following in your Parser method:
NameTable nameTable = new NameTable();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nameTable);
nsmgr.AddNamespace("z", "#RowsetSchema");
List<XmlNodeList> rows = (from row in data.AsEnumerable()
select row.SelectNodes("//z:row", nsmgr)).ToList();
I'm not at a place where I can test right now, but I believe at least part of the issue is your omission of namespaces in your query -- rather than "data/row", try "rs:data/z:row".