I'm trying to get the 3rd level names from a XML.
I found this but it gives me also the 4th level, which i don't want.
How should i do it?
XDocument xdoc = XDocument.Load(path + #"\Pages\Results\Target_XML.xml");
foreach (var name in xdoc.Root.Element("Veg").DescendantNodesAndSelf().OfType<XElement>().Select(x => x.Name).Distinct())
{
Console.WriteLine(name);
}
Example (I want just the Tom and Car as strings, without Name and Cal) -
This is the XML:
<DEV>
<Veg>
<Tom>
<Name>aa</Name>
<Cal>99</Cal>
</Tom>
<Car>
<Name>aa</Name>
<Cal>99</Cal>
</Car>
</Veg>
<Fru>
<Ban>
<Name>aa</Name>
<Cal>99</Cal>
</Ban>
</Fru>
</DEV>
Using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Runtime.InteropServices;
namespace ConsoleApplication23
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<string> strings = doc.Elements().Elements().Elements().Select(x => x.Name.LocalName).ToList();
}
}
}
You can reference the child nodes with XElement's ChildNodes property. Like this:
XmlNodeList childNodes = xdoc.Root.Element("Veg").ChildNodes;
In this case, the childNodes list would contain the 3rd level nodes you want.
var l_RootElement = XElement.Load(path + #"\Pages\Results\Target_XML.xml");
foreach (var l_VegElement in l_RootElement.Elements("Veg").Elements()) {
Console.WriteLine(l_VegElement.Name);
}
Related
I can't parse the attribute value from this file, I used Linq and the standard library. Object reference error. Need attribut's value "RequeryNumber".
XML file
Excel Query:
exctract = XML.DocumentElement
.SelectSingleNode("//KPOKS/ReestrExtract/DeclarAttribute")
.Attributes
.getNamedItem("RequeryNumber").Text
SelectSingleNode() uses XPath to find XML nodes that fulfill the filter.
There are several ways to get what you want. If RequeryNumber only exists on one node, you could do like this:
var attribute = xDoc.DocumentElement
.SelectSingleNode("//*[#RequeryNumber]/#RequeryNumber");
MessageBox.Show("text" + attribute.InnerText);
[#RequeryNumber] finds the node which has an attribute named "RequeryNumber".
/#RequeryNumber extracts that specific attribute, on which you can get the value using the InnerText property.
I would suggest you take a look at: XPath cheatsheet
I had one error on following line in the xml that I fixed
I parsed below your xml and needed to add the namespace to get the XElement using Xml Linq.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XNamespace ns = doc.Root.GetDefaultNamespace();
XElement declarAttribute = doc.Descendants(ns + "DeclarAttribute").FirstOrDefault();
}
}
}
I have a XML file structure like this:
<root>
<list>
<item1>item 1</item1>
<item2>item 2</item2>
<item3>item 3</item3>
<item4>item 4</item4>
</list>
<generated-items>
<item5>item 5</item5>
<item6>item 6</item6>
</generated-items>
</root>
What I want to do is move the generated-list node and its sub-nodes to make it a sub-node within the list node.
So the final result should be like this:
<root>
<list>
<item1>item 1</item1>
<item2>item 2</item2>
<item3>item 3</item3>
<item4>item 4</item4>
<generated-items>
<item5>item 5</item5>
<item6>item 6</item6>
</generated-items>
</list>
</root>
Hope someone can help me find the best solution for this.
Use xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement root = doc.Root;
XElement list = root.Element("list");
XElement items = root.Element("generated-items");
list.Add(new XElement(items));
items.Remove();
}
}
}
I'm trying to get a child element's value where another child element value equals to a value,
for example I have this xml file:
<CATALOG>
<game>
<name>Assassins Creed Origins</name>
<picture>pic1</picture>
<torrent>file1</torrent>
</game>
<game>
<name>mylifeisdone</name>
<picture>pic2</picture>
<torrent>file2</torrent>
</game>
</CATALOG>
I want to get picture value where name equals to mylifeisdone
Using Xml Linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<XElement> games = doc.Descendants("game").ToList();
string picture = games.Where(x => (string)x.Element("name") == "mylifeisdone").Select(x => (string)x.Element("picture")).FirstOrDefault();
}
}
}
The easiest way I could think of is using XDocument:
XDocument doc = XDocument.Parse(#"
<CATALOG>
<game>
<name>Assassins Creed Origins</name>
<picture>pic1</picture>
<torrent>file1</torrent>
</game>
<game>
<name>mylifeisdone</name>
<picture>pic2</picture>
<torrent>file2</torrent>
</game>
</CATALOG>");
var picture = doc.Descendants("game")
.First(g => g.Element("name").Value == "mylifeisdone")
.Element("picture").Value;
This first gets all elements "game" and searches for the first element, of which the name element has the value "mylifeisdone"; after that, it retrieves the value of the "picture" element.
Note: you may need the namespace System.Xml.Linq and, if you are reading the XML from a file, use XDocument.Load("path").
Background
This is my small XML file I made online.
<?xml version="1.0"?>
<movement>
<skill id = "2">
<cooldown>5</cooldown>
</skill>
<skill id = "3">
<cooldown>10</cooldown>
</skill>
</movement>
This is some code I have so far to try to parse it.
string dataPath = Application.dataPath + "/Resources/XML/Skills/";
DirectoryInfo xmlFolder = new DirectoryInfo (dataPath);
FileInfo[] files = xmlFolder.GetFiles ("*.xml");
// Loops through each XML file
foreach (FileInfo file in files) {
XmlDocument xdoc = new XmlDocument ();
xdoc.Load (file.ToString ());
XmlNodeList nodes = xdoc.DocumentElement.SelectNodes ("/movement");
foreach (XmlNode node in nodes) { // Movement Layer
foreach (XmlNode skillNode in node.ChildNodes) {
print (skillNode.Value);
}
}
}
Problem
I am able to access the 5 and 10 values for cooldown, but cannot get the "id" value of the skill. The reason I'm trying to do this is to read the skill IDs into my game and store the information. I pretty much exhausted almost all the methods denoting from XmlNode, such as value and name, but it only returns "skill", and not the value of skill, such as 2 or 3. I feel like I'm missing something really simple here, but I'm having difficulty finding the correct terminology or phrasing for this issue.
LINQ To XML would make this parsing simpler...
static void Main(string[] args)
{
var doc =
#"<?xml version=""1.0""?>
<movement>
<skill id = ""2"" >
<cooldown> 5 </cooldown>
</skill>
<skill id = ""3"" >
<cooldown> 10 </cooldown>
</skill>
</movement> ";
var root = XDocument.Parse(doc);
foreach (var skill in root.Descendants("skill"))
{
Console.WriteLine("Skill: {0} \t CoolDOwn: {1}",
(int)skill.Attribute("id"),
skill.Element("cooldown").Value);
}
Console.ReadLine();
}
Using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("skill").Select(x => new {
id = (int)x.Attribute("id"),
coolDown = (int)x.Element("cooldown")
}).ToList();
}
}
}
I would not use XMLDocument for querying purposes IMHO. I find XDocument to be an easier extension off of System.Xml.Linq;
EG:
using System;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleTester
{
class Program
{
static void Main(string[] args)
{
//Here I am mocking your file statically, you could iterate here through a file system.
var xml =
"<?xml version=\"1.0\"?><movement><skill id = \"2\"><cooldown>5</cooldown></skill><skill id = \"3\"><cooldown>10</cooldown></skill></movement>";
//Just parse the file from the text obtained from a StreamReader or similar.
var xdoc = XDocument.Parse(xml);
//Chain the events of finding the node(s) you want with 'Elements' then continuing on to more, then you want an Attribute and not a node. Then select it's value.
xdoc.Elements("movement").Elements("skill").Attributes("id")
.Select(x => x.Value)
.ToList()
.ForEach(x => Console.WriteLine(x));
Console.ReadLine();
}
}
}
I have an XML Documnet consisting parent nodes and child nodes,
<?xml version='1.0' encoding='UTF-8'?>
<response>
<system_timestamp>2016-10-21 13:40:28</system_timestamp>
<response_data>
<status>Active</status>
<profile>
<first_name>John</first_name>
<last_name>Abraham</last_name>
<ship_to_address>
<address_1>null</address_1>
<address_2>null</address_2>
<city>null</city>
<state>null</state>
<postal_code>null</postal_code>
</ship_to_address>
</profile>
</response_data>
</response>
I am having few null valued child nodes like <address_1> and <address_2>. So, now how would I remove those null values of my child nodes. I tried
doc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();
But this is not working . And i am using this
XmlDocument doc = new XmlDocument();
doc.LoadXml(_value);
code to parse xml document. Do we have any other methods to remove using XMLDocument instead of XElement.
e.Value isn't a null reference or an empty string - it's the string "null" because that's the value in your element.
You want:
doc.Descendants().Where(e => (string) e == "null").Remove();
When removing an item from a list you must removed from last item to first item otherwise the indexing gets screwed up and not all the items get removed. Try this
sing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
List<XElement> nulls = doc.Descendants().Where(x => (string)x == "null").ToList();
for (int i = nulls.Count - 1; i >= 0; i--)
{
nulls[i].Remove();
}
}
}
}