I have an XML as below. I will have to fetch the title when the path is d:\mypath. I tried below one but it is not giving as expected. I would like implement it in LINQ to XML.
My code:
XDocument xdoc = XDocument.Load(file);
string mypath = #"D:\\Mypath";
var result = xdoc.Descendants("child")
.Where(i => (string)i.Element("content").Element("path") == mypath)
.Select(i => (string)i.Element("title")).FirstOrDefault();
For now I have finished my task using XPathSelectElement as below, but I am interested to in LINQ query :
string a = (string)xdoc.XPathSelectElement(
"//child/content[path='" + mypath + "']/../doc_attributes/title");
Sample XML:
<parent>
<doc>
<order>testorder</order>
<preorder>yes</preorder>
</doc>
<childs>
<child>
<doc_attributes>
<id>090015b3804fb931</id>
<title>CTA</title>
</doc_attributes>
<content>
<path>D:\\Mypath</path>
</content>
</child>
</childs>
</parent>
You're close, you're just forgetting to check the Value property
.Where(i => i.Element("content").Element("path").Value == mypath)
Related
Hi I try to read an xml file with LINQ.
The name of the file is:categorizedBooks.xml
and the content of the file looks like this:
<category name=".NET">
<books>
<book>CLR via C#</book>
<book>Essential .NET</book>
</books>
</category>
The code for reading the file looks like this:
XElement rootss = XElement.Load(#"D:/categorizedBooks.xml");
XElement dotNetCategoryss = rootss.Element("category");
XAttribute namehallo = dotNetCategoryss.Attribute("name");
XElement booksss = dotNetCategoryss.Element("books");
IEnumerable<XElement> bookElements = booksss.Elements("book");
Console.WriteLine((string)dotNetCategoryss);
foreach (XElement bookElement in bookElements)
{
Console.WriteLine(" - " + (string)bookElement);
}
But i get null on this line:
XAttribute namehallo = dotNetCategoryss.Attribute("name");
So how to fix this , so that it not will be null?
Thank you
Your doc root is the category element - try:
XAttribute namehallo = rootss.Attribute("name");
Console.WriteLine(namehallo.Value);
You'll have to change your other XElement references similarly
instead of XElement.Load use XDocument.Load or XDocument.Parse
var xml = #"
<category name='.NET'>
<books>
<book>CLR via C#</book>
<book>Essential .NET</book>
</books>
</category>";
var document = XDocument.Parse(xml);
// returns: .NET
var category = document
.Element("category")
.Attributes("name")
.Select(p => p.Value);
// returns: CLR via C#, Essential .NET
var books = document
.Descendants("book")
.Select(p => p.Value);
I am trying get the email value under author node in C#. But nothing is coming. My Code is=
XDocument xDoc = XDocument.Parse("myxml");
var foos = from xelem in xDoc.Descendants("author")
select xelem.Element("email").Value;
XML which i am using is -
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:batch="http://schemas.google.com/gdata/batch"
xmlns:gContact="http://schemas.google.com/contact/2008" xmlns:gd="http://schemas.google.com/g/2005"
xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
<id>yogeshcp13#gmail.com</id>
<updated>2015-02-09T04:03:31.220Z</updated>
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
<title type="text">Yogesh Adhikari's Contacts</title>
<link rel="alternate" type="text/html" href="https://www.google.com/"/>
<link rel="next" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/yogeshcs2003%40gmail.com/full?max-
results=1&start-index=2"/>
<author>
<name>Yogesh Adhikari</name>
<email>yogeshcp13#gmail.com</email>
</author>
<generator version="1.0" uri="http://www.google.com/m8/feeds">Contacts</generator>
<openSearch:totalResults>3099</openSearch:totalResults>
<openSearch:startIndex>1</openSearch:startIndex>
<openSearch:itemsPerPage>1</openSearch:itemsPerPage>
</feed>
Can someone point out what is wrong?
Thanks
You need to specify the namespace along with the name when getting the descendants.
XDocument xDoc = XDocument.Parse("myxml");
string ns = xDoc.Root.Name.Namespace;
var foos = from xelem in xDoc.Descendants(ns + "author")
select xelem.Element(ns + "email").Value;
Alternatively, you can find your nodes by getting an enumeration over all descendants, then filtering by LocalName. If email is a node only within authors in your schema, you can also avoid the unnecessary step of drilling down from author nodes, and just find your email nodes directly:
var foos = xdoc.Descendants().Where(e => e.Name.LocalName == "email");
XDocument xDoc = XDocument.Load("myxml.xml");
var foos = xDoc.Descendants().Where(e => e.Name.LocalName == "email");
Console.WriteLine(foos.FirstOrDefault().Value);
Use Load method if you are refering to xml file else parse should be fine. Also make sure xml is along with your binaries' folder if not using specific path.
I have an XML file with the following structure:
<doc>
<rootelement>
<childelement id="0" />
<childelement id="1" />
.
.
</rootelement>
</doc>
I want to find the highest numeric value of the id attribute
The idea I have in mind is something like:
int highest = -1;
foreach(var node in xmldoc.SelectNodes("//doc/rootelement/childelement"))
{
highest = Math.Max(GetID(node), highest);
}
where GetID(XMLNode) would retrieve the value of the attribute of the current node.
Is there a more compact (or more efficient) XPath expression to do that?
You can use Linq to Xml:
var xdoc = XDocument.Load(path_to_xml);
var maxId = xdoc.XPathSelectElements("//doc/rootelement/childelement")
.Max(c => (int)c.Attribute("id"));
Or without XPath:
var maxId = xdoc.Root.Elements("rootelement")
.Elements("childelement")
.Max(c => (int)c.Attribute("id"));
With XmlDocument:
var maxId = doc.SelectNodes("//doc/rootelement/childelement")
.Cast<XmlElement>()
.Max(c => Int32.Parse(c.Attributes["id"].Value));
Use Linq to XML.
string xml =
#"<doc>
<rootelement>
<childelement id='0' />
<childelement id='1' />
</rootelement>
</doc>";
var doc = XDocument.Parse(xml);
int max = doc.Descendants("childelement").Max(e => (int)e.Attribute("id"));
I have an XML file
<Person>
<PersonItem id="0">
<Time>1/8/2014</Time>
<Step><![CDATA[Normal]]></Step>
<HasAddress/>
<Address/>
</PersonItem>
<PersonItem id="1">
<Time>1/8/2014 3:21:45 PM</Time>
<Step><![CDATA[Normal]]></Step>
<HasAddress/>
<Address/>
</PersonItem>
<PersonItem id="2">
<Time>1/8/2014</Time>
<Step><![CDATA[Normal]]></Step>
<HasAddress>Main</HasAddress>
<Address>
<AddressItem id="0" location=5>
<Address>15 Oak</Address>
</AddressItem>
<AddressItem id="1" location=7>
<Address>12 Maple</Address>
</AddressItem>
<AddressItem id="2" location=8>
<Address>30 Beech</Picture>
</AddressItem>
</Address>
</PersonItem>
</Person>
I want to put to retrieve the information and send some of it to a database. I've tried several different ways of dealing with this and I believe I'm close. Here is the Linq I tried.
public void DoIt(fileName)
{
XElement xml = XElement.Load(fileName);
var items = from item in xml.Elements("PersonItem")
where (from x in item.Elements("HasAddress")
where x.Element("HasAddress") != null
select x).Any()
select item;
Array.ForEach(items.ToArray(),
o=>Console.WriteLine(o.Element("Time").Value));
Console.ReadLine();
}
The problem is nothing is being returned.
Could be just a typo but in your xml file there is this tag error.
<Address>30 Beech</Picture>
which should be:
<Address>30 Beech</Address>
Try this:
XElement xml = XElement.Load(fileName);
var items = xml.Descendants("PersonItem")
.Where(x => (string)x.Element("HasAddress") != null)
.Select(x => x);
XDocument xml = XDocument.Load("Input.xml");
var items = from item in xml.Root.Elements("PersonItem")
where !string.IsNullOrEmpty((string)item.Element("HasAddress"))
select item;
For your sample XML document returns only the last PersonItem element.
I'm trying to get all elements with a given value, "John", from an xml document.
Is this possible with LINQ to XML?
What I want to achieve is to replace all "John" values with "Wayne". I know this can easily be done with xslt, but I need to do this by code.
My XML:
<Root>
<Parents>
<Parent>
<Name>John</Name>
<Age>18</Age>
</Parent>
<Parent>
<Name>John</Name>
<Age>25</Age>
</Parent>
<Parent>
<Name>Peter</Name>
<Age>31</Age>
</Parent>
</Parents>
</Root>
I have tried this:
XmlDocument doc = new XmlDocument();
doc.Load(#"C:/Temp/test.xml");
var elements = doc.Elements().Where(w => w.Value == "John");
foreach (var element in elements)
{
element.Value = "Wayne";
}
You may use System.Xml.Linq.XDocument. It's more easy to work with.
XDocument doc = XDocument.Load(your file path);
var elements = doc.Descendants("Name").Where(i => i.Value == "John");
foreach (var element in elements)
{
element.Value = "Wayne";
}
doc.Save(your save file path);
Here is the output:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Parents>
<Parent>
<Name>Wayne</Name>
<Age>18</Age>
</Parent>
<Parent>
<Name>Wayne</Name>
<Age>25</Age>
</Parent>
<Parent>
<Name>Peter</Name>
<Age>31</Age>
</Parent>
</Parents>
</Root>
Here is an approach that will get all elements with the value John, regardless of what element (although only at the same level; you'd have to modify it to look at different levels too; you could use the Descendants approach described previously):
XDocument doc = XDocument.Load(#"C:\temp\test.xml");
var ns = doc.Root.GetDefaultNamespace();
var elements = doc.Element(ns + "Root").Element(ns + "Parents").Elements(ns + "Parent").Elements().Where(w => w.Value == "John");
foreach (var element in elements)
{
element.Value = "Wayne";
}
var stream = new FileStream(#"C:\temp\test.xml", FileMode.Create);
doc.Save(stream);