Here is my XML file
<Drive>
<Data0 Key="1" Name="AA" />
<Data1 Key="2" Name="BB" />
<Data2 Key="4" Name="CC" />
<Data3 Key="10" Name="WW" />
<Data4 Key="11" Name="WE" />
<Data5 Key="12" Name="VW" />
</Drive>
I want to select all nodes where their [Key] start with "1" using C# and XML XPATH
I tried this:
XmlNodeList FKNodes = node.SelectNodes("*/* [#Key like '1*']")
You can use * to select element of any name, and use starts-with() function to match the Key attribute value partially :
XmlNodeList FKNodes = node.SelectNodes("//*[starts-with(#Key, '1')]")
xpath demo
Related
I have to read some values from XML,below is my sample XML
<?xml version="1.0" encoding="utf-16"?>
<ParentNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ChildNode>
<GrandChild Name="title" Value="Mr" />
<GrandChild Name="Name" Value="Test" />
<GrandChild Name="Age" Value="25" />
<GrandChild Name="Gender" Value="Male" />
</ChildNode>
</ParentNode>
I have to read values of Name and Age nodes, this is how I am doing
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(myXMLstring);
var nodes = xmlDoc.SelectNodes("/ParentNode/ChildNode");
foreach (XmlNode childrenNode in nodes)
{
}
but this code is running for only once, I tried this inside loop,buts its not running
var gchild= childrenNode.SelectNodes("/GrandChild");
foreach (XmlNode namevalue in gchild)
{
}
How can I get the values of Name and Age node?
Your XML contains only a single ChildNode so the XPATH expression /ParentNode/ChildNode will return only a single result. If you wanted to iterate over the grandchildren you should use /ParentNode/ChildNode/GrandChild or //GrandChild, eg:
var nodes = xmlDoc.SelectNodes("/ParentNode/ChildNode/GrandChild");
The result will be the same.
A single slash at the start of an XPath expression means that the path starts from the root, so /GrandChild returns nothing because there is no GrandChild note at the root level. A double slash // means wherever in the hierarchy, so //GrandChild will return all GrandChild nodes in the file
SelectNodes uses XPath expressions. In XPath, if the expression stars with / it'll start selecting relative to root.
Just use a relative xpath expression. In your case:
var gchild = childrenNode.SelectNodes("./GrandChild");
Or the equivalent:
var gchild = childrenNode.SelectNodes("GrandChild");
Or, if you only aim to iterate over those GrandChild elements, there's no reason to select the ChildNode first, you could iterate directly:
var nodes = xmlDoc.SelectNodes("/ParentNode/ChildNode/GrandChild");
I need to change
<Test Language="English" Id="0" />
to
<Exam Language="English" Id="0" />
How to the replace node names with new name and keep the attributes ?
You can use Name property
var xdoc = XDocument.Load("input.xml");
var nodes=xdoc.Descendants("Test").ToList();//Get all "Test" node
nodes.ForEach(d => d.Name = "Exam "); // Set name to 'Exam'
xdoc.Save("output.xml");
My XML looks like this:
<Settings>
<Display_Settings>
<Screen>
<Name Name="Screen" />
<ScreenTag Tag="Screen Tag" />
<LocalPosition X="12" Y="81" Z="28" />
<Width Width="54" />
<Height Height="912" />
</Screen>
<Screen>
<Name Name="Screen" />
<ScreenTag Tag="Screen Tag" />
<LocalPosition X="32" Y="21" Z="28" />
<Width Width="54" />
<Height Height="912" />
</Screen>
</Display_Settings>
</Settings>
How am I able to read in the two different Local Position X attribute values from two different nodes that have the same name?
Edit
Sorry, forgot to add the code I have at the moment that reads in a singular local position attribute value from one screen node:
var xdoc = XDocument.Load("C:\\Test.xml");
var screenPosition = xdoc.Descendants("Screen").First().Element("LocalPosition");
int screenX1 = int.Parse(screenPosition1.Attribute("X").Value);
XPath would look like this:
/Settings/Display_Settings/Screen/LocalPosition/#X
You can use online tool like this: http://www.freeformatter.com/xpath-tester.html#ad-output to test your XPath's.
Also, there's a good tutorial here: http://www.w3schools.com/xpath/
As long, as question was updated, code:
var xdoc = XDocument.Load(#"C:\darbai_test\so_Test.xml");
var screenPosition = xdoc
.Descendants("Screen")
.Descendants("LocalPosition")
.Attributes("X");
foreach (var xAttribute in screenPosition)
{
Console.WriteLine(xAttribute.Value);
}
Console.ReadKey();
I was asked today to look at a new project - reading in some XML and doing some analysis. I know a little C#. I have gotten this far with this code that so far works. I get the 4 node lists successfully. I have a couple problems. First I am not sure how to access what is in the tag on any of the nodes in any of the lists. Second, I'd prefer to be able to use LINQ queries but XmlNodeList doesn't seem to support that syntax. In the sample XML below, I'd like to be able to get all the vdisks that belong to a particular IO Group or mdisk as determined by io_group_name or mdisk_grp_name property. Most of what I looked at gave examples for accessing the [Attribute] list and searches all used properties/atttributes interchanged.
What I tried is also below, it gave a null value exception. The Attributes list only has one attribute. I can't find any examples to do what I want and it isn't clear from inspecting the node in the debugger what I need to access to do what I want.
//this works
XmlTextReader reader = new XmlTextReader(_InputFile);
XmlDocument doc = new XmlDocument();
doc.Load(reader);
XmlNodeList clusterlist = doc.SelectNodes("//object[#type='cluster']");
XmlNodeList controllerlist = doc.SelectNodes("//object[#type='controller']");
XmlNodeList mdisklist = doc.SelectNodes("//object[#type='mdisk']");
XmlNodeList vdisklist = doc.SelectNodes("//object[#type='vdisk']");
// this did not work - got null value exception
foreach (XmlNode vdisknode in vdisklist)
{
string str = vdisknode.Attributes["mdisk_grp_name"].Value;
}
A sample of the XML:
<object type="vdisk">
<property name="id" value="0" />
<property name="name" value="nim01_vd06_gmt" />
<property name="IO_group_id" value="0" />
<property name="IO_group_name" value="ossvc06_iogrp0" />
<property name="status" value="online" />
<property name="mdisk_grp_id" value="0" />
<property name="mdisk_grp_name" value="T1_OSIBM06_MDG1" />
<property name="capacity" value="644245094400" />
<property name="type" value="striped" />
</object>
object node has only one attribute: type
string type = vdiskNode.Attributes["type"].Value;
property node has two attributes: name and value:
string name = propertyNode.Attributes["name"].Value;
string value = propertyNode.Attributes["value"].Value;
What you need I deem is to extend the XPath query:
"//object[#type='vdisk']/property[#name='mdisk_grp_name']/#value"
Or use LINQ to XML:
from obj in doc.Load(xml).Root.Elements("object")
where (string)obj.Attribute("type") == "vdisk"
from prop in obj.Elements("property")
//where (string)prop.Attribute("name") == name
select prop.Value
I am looking for an occurance of a certain tag in my xml file. If i find an occurance then i want to get its immediate children tags (not their child tags)
Is this possible? If so what do i need to look in to ?
Thanks
<Footballer>
<Player>
<Number />
<Team>
<Division />
<Position />
</Team>
<Country />
<Birthdate />
</Player>
</Footballer>
if player was the input for example then the tags Number, Team, Country Birthdate would be returned
You can try to use linq to xml:
var doc = XDocument.Load(xmlFilePath);
List<string> urlList = doc.Descendants("yourparent");
.Select(x => insert value you want to select).ToList();