what's wrong in this LINQ query - c#

I have the following XML
<School Version="30">
<Math>
<Lesson1 Type="Active">Introduction</Reset_mode>
<Lesson2 Type="Active">Fundamentals</Reset_mode>
</Math>
</School>
I want to get the subelements lesson1, lesson2
I load the XML in XDocument
I have to question - what's wrong in this query
var nodes = from C in document.Element("School").Elements()
where document.Element("School").Elements().Contains(t => t.Name == "Math")
select C ; //shortcutsXMLDocument.SelectNodes(Query);
and it raise and error.
Also can I use XPath with XDocument?

You are looking for a ShortcutList element :
Element("ShortcutList")
Which does not exists.
You should write this to get subLessons :
var items = document.Element("School").Element("Math").Elements();
foreach(var item in items)
{
DoSomething(item);
}

LINQ to XML:
from subject in XDocument.Load(xml).Element("School").Elemens()
where subject.Name == "Math"
select subject.Elements();
XPath using XmlDocument:
var doc = new XmlDocument();
doc.LoadXml(xml);
var nodes = doc.SelectNodes("School/Math/Lesson1 or School/Math/Lesson2");

document.Decendants("Math");
yields you a IEnumrable with your two elements.
it's equal to the xpath //Math

Xpath case used on XElement/XDocument from this namespace System.Xml.XPath.
here is your query for path...
var nodes = from C in document.XPathSelectElements("./Math")
select C; //shortcutsXMLDocument.SelectNodes(Query);

Related

Get a xml element with specific attribute value in c#

I need to get a value of a SubTopic element which has an attribute called "Name" with specific value. I do it this way;
IEnumerable<XElement> list =
(from el in xdoc.Elements()
where (string)el.Attribute("Name") == "creatingTests"
select el);
The collection has zero elements.
I tried putting xdoc.Elements("SubTopic") instead of empty parameter, but with no success.
My XML file structure;
<?xml version="1.0" encoding="windows-1250" ?>
<Help Title="TestTool - tematy pomocy">
<Topic Name="creatingTests" Title="Tworzenie testów">
<SubTopic Name="saveload" Title="Zapis i odczyt z pliku">
Content
</SubTopic>
</Topic>
</Help>
How can I get that value of Help/Topic(Name="creatingTests")?
xdoc is of course XDocument object with loaded xml and it does have the content of my file.
xdoc.Elements() returns only one element - the Root of XML tree (it's <Help> element in your example.
Change your query to:
IEnumerable<XElement> list =
(from el in xdoc.Root.Elements()
where (string)el.Attribute("Name") == "creatingTests"
select el);
It returns collection with one element. Use First or FirstOrDefault to get it as single item, not a collection:
XElement item = (from el in xdoc.Root.Elements()
where (string)el.Attribute("Name") == "creatingTests"
select el).FirstOrDefault();
Here's an alternative by using System.Xml.XPath:
using System.Xml.Linq;
using System.Xml.XPath;
class Program
{
static void Main(string[] args)
{
var xdoc = XDocument.Load("input.xml");
var subTopic = xdoc
.XPathSelectElement("//Topic[#Name='creatingTests']/SubTopic");
}
}
Very easy and simplest way is to use XSLT..
1.Create an XSLT Template.
2.Call it in c#.
xmlDaynamic.DocumentContent = "Your XML Input";
xmlDaynamic.TransformSource = "YourTemplate with extension";
3.Your task is done.
4.xmlDaynamic is a server control.
Try using XPATH
http://support.microsoft.com/kb/308333
"//Topic[#Name='creatingTests']"

Reader Nodes from XML

I have this XML and i try to read the scpefic nodes but not work =(
the my code is:
XmlDocument doc = new XmlDocument();
doc.Load("https://apps.db.ripe.net/whois/search.xml?query-string=193.200.150.125&source=ripe");
XmlNode node = doc.SelectSingleNode("/whois-resources/objects/attributes/descr");
MessageBox.Show(node.InnerText);
the two circled values on image
Url: https://apps.db.ripe.net/whois/search.xml?query-string=193.200.150.125&source=ripe
it is possible?
When you are looking for a node which has an attribute "name" set to a particular value, you need to use different syntax.
You're looking for something like:
XmlNode node = doc.SelectSingleNode("/whois-resources/objects/object/attributes/attribute[#name=\"descr\"]");
XmlAttribute attrib = node.Attributes["value"];
MessageBox.Show(attrib.Value);
This will select your second node example, get the value of the value attribute, and display it.
How about using Linq To Xml?
var xDoc = XDocument.Load("https://apps.db.ripe.net/whois/search.xml?query-string=193.200.150.125&source=ripe");
var desc = xDoc.Descendants("attribute")
.Where(a => (string)a.Attribute("name") == "descr")
.Select(a => a.Attribute("value").Value)
.ToList();
or
var desc = xDoc.XPathSelectElements("//attribute[#name='descr']")
.Select(a => a.Attribute("value").Value)
.ToList();

LINQ to XML to read Hierarchal XML Document

I have an XML as an XDocument. How can I use LINQ to read an attribute x if SubMain y?
<Main>
<SubMain Name="SubMain1">
<Attribute1>Value1</Attribute1>
<Attribute2>Value2</Attribute2>
<Attributen>Valuen</Attribute2>
<SubMain>
<SubMain Name="SubMain2">
<Attribute1>Value1</Attribute1>
<Attribute2>Value2</Attribute2>
<Attributen>Valuen</Attribute2>
<SubMain>
</Main>
Quick and dirty
var xmlString = #"<Main>
<SubMain Name=""SubMain1"">
<Attribute1>Value1</Attribute1>
<Attribute2>Value2</Attribute2>
<Attributen>Valuen</Attributen>
</SubMain>
<SubMain Name=""SubMain2"">
<Attribute1>Value1</Attribute1>
<Attribute2>Value2</Attribute2>
<Attributen>Valuen</Attributen>
</SubMain>
</Main>";
var xDoc = XDocument.Parse(xmlString);
var item = (from el in xDoc.Descendants("SubMain")
where el.Attribute("Name").Value == "SubMain2"
select el);

Convert the following Linq to xml to .net 2.0

I am recently working on a .net 2.0 project I have to read some xml files and replace certain elements value.
Wondering how you do it the following not using linq to xml?
IEnumerable<XElement> cities= xmldoc.Descendants("City")
.Where(x => x.Value == "London");
foreach (XElement myElem in cities)
{
myElem.ReplaceWith(new XElement("City", "NewCity"));
}
or
var xElement = xdoc.Descendants("FirstName").Where(x => x.Value == "Max").First();
xElement.ReplaceWith(new XElement("FirstName", "NewValue");
Any suggestions
You can consider using XmlDocument, like this:
string xmlFile = "<xml><data<test /><test /><test /><test /></data></xml>";
var xmlDoc = new XmlDocument();
xmlDoc.Load(xmlFile);
var oNodes = xmlDoc.SelectNodes("//test");
foreach (var oNode in oNodes)
{
oNode.InnerText = "bla bla";
}
xmlDoc.Save("..path to xml file");
(In your case you can use InnerXml property of the document)
http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx
To selectNodes you should pass XPath Query, reference can be found:
http://www.w3schools.com/xpath/
Also if you XML contains namespace, you need to use XmlNamespaceManager:
http://msdn.microsoft.com/en-us/library/system.xml.xmlnamespacemanager.aspx
Otherwise xpath won't work.
You will need to use XmlDocument and query it using XPath with SelectNodes.
It will not be as nice and succint.

Most elegant way to query XML string using XPath

I'm wondering what the most elegant way is in C# to query a STRING that is valid xml using XPath?
Currently, I am doing this (using LINQ):
var el = XElement.Parse(xmlString);
var h2 = el.XPathSelectElement("//h2");
Simple example using Linq to XML :
XDocument doc = XDocument.Parse(someStringContainingXml);
var cats = from node in doc.Descendants("Animal")
where node.Attribute("Species").Value == "Cat"
select node.Attribute("Name").Value;
Much clearer than XPath IMHO...
Just for the record, I did not want to go with Linq2XML but XPath and found this way:
var xPathDoc = new XPathDocument(new StringReader("your XML string goes here"));

Categories