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();
}
}
}
Related
//I would like to get some advice on how to replace the node value of a element in XML using XMLElement or XElement. Right now I'm trying it with XMLElement but the compiler gives me only errors or the XML replace the whole document insted of selected node. I have a XML/XSD sample that I need to fill with data and create like 500 XML a day but I cant insert the data into the right elements.
I expect that I can replace / insert data into the element value. Like I want to change the City text value. I have a table with content and based on the filled data I need to add it into specific XML elements and save.
As for now every sample code I found and some I covered up did give compile errors / null reference object( at assigning InnerText) or deleted all the elements and added just one line with my text value.
Te code below gives me ''Object reference not set to an instance of an object.'
' at .InnerText. Actually the declatarion of SelectSingleNode("ID") return me also a null.
-<Receiver>
-<ID>
<RNumber>9999999999</RNumber>
<Name>ABC AGD sp. z o. o.</Name>
</ID>
-<Address>
-<AddressSpec>
<Country>PL</Country>
<Street>Kwiatowa</Street>
<HouseNum>1</HouseNum>
<City>Warszawa</City>
</AddressSpec>
</Address>
<Email>test#test.pl</Email>
<Phone>667444555</Phone>
</ID>
-</Receiver>
using System.IO;
using System.Net;
using System.Xml;
using System.Xml.Linq;
class ReplaceXMLData
{
public static void Main(Args _args)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(//path/sample.xml);
System.Xml.XmlElement root = doc.DocumentElement;
System.Xml.XmlElement Street = doc.SelectSingleNode("Street");
Street.innertext = "random";
doc.AppendChild(root);
doc.Save(path);
info("Details added Successfully");
}}
Here is solution using Xml Linq (XDocument). You need to use Decendants with FirstOrDefault
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication15
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement id = doc.Descendants("ID").FirstOrDefault();
}
}
}
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").
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);
}
How would code an iteration to loop through the parent tag on a xml file as below:
<collection>
<parent>
<child1>DHL</child1>
<child2>9000000131</child2>
<child3>ISS Gjøvik</child13>
<child4>ISS Gjøvik</child4>
<child5>ISS Gjøvik</child5>
<child6>9999000000136</child6>
</parent>
<parent>
<child1>DHL</child1>
<child2>9000000132</child2>
<child3>ISS Gjøvik</child13>
<child4>ISS Gjøvik</child4>
<child5>ISS Gjøvik</child5>
<child6>9999000000136</child6>
</parent>
<parent>
<child1>DHL</child1>
<child2>9000000134</child2>
<child3>ISS Gjøvik</child13>
<child4>ISS Gjøvik</child4>
<child5>ISS Gjøvik</child5>
<child6>9999000000136</child6>
</parent>
</collection>
I need to insert the value of child1 as the primary key into the DB.
Have you tried the XmlReader? What do you have so far? Please show us some code. Just a reminder, StackOverflow is a helpdesk, not a programming service.
I see DHL in one of the tags. If that refers to the postal delivery company, they have an API (SDK) that is easy to use from within .NET code..
If you want to use XML (de)serialization that I would suggest that you start reading the System.Xml.Serialization namespace documentation. Microsoft has provided more than enough documentation and examples.
Link to namespace docs: https://msdn.microsoft.com/en-us/library/system.xml.serialization(v=vs.110).aspx
Here are some examples that contains anything that you would need to deserialzation the xml document to a poco class:
https://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx
Assuming your xml is in the string variable xml:
var xdoc = XDocument.Parse(xml);
foreach (var parentEls in xdoc.Root.Elements("parent"))
{
string child1Value = parentEls.Element("child1").Value;
// your logic using child1 value
}
Note that your xml is malformed - <child3> is closed by </child13>.
Using xml linq to parse everything
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("parent").Select(x => new {
child1 = (string)x.Element("child1"),
child2 = (string)x.Element("child2"),
child3 = (string)x.Element("child3"),
child4 = (string)x.Element("child4"),
child5 = (string)x.Element("child5"),
child6 = (string)x.Element("child6")
}).ToList();
}
}
}
I found some examples stackoverflow of using a xml to linq parser. My xml has a namespace, so I tried setting that as well (though I would of thought you could read that in a from the file?)
Anyway, when I run the c#/linq code it does not recognise the elements in the xml. Unless I remove the xmlns tag from the xml file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
XDocument document = XDocument.Load("C:\\NewCredential.xml");
XNamespace ns = "http://myworld.org/CredCentral.xsd";
var usernames = from r in document.Descendants(ns + "Credential")
select r.Element("Username").Value;
foreach (var r in usernames)
{
Console.WriteLine(r.ToString());
}
Console.ReadLine();
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<CredCentral xmlns="http://myworld.org/CredCentral.xsd">
<Credential>
<CredentialId>123456789</CredentialId>
<Username>johnsmith</Username>
<Password>password</Password>
</Credential>
</CredCentral>
Any help would be appreciated, thank you kindly.
You need to specify the namespace with element name as well:
from r in document.Descendants(ns + "Credential")
select (string)r.Element(ns + "Username");
Also I recommend you use an explicit cast instead of using Value property that will prevent the possible exceptions.
You're almost there, you just have to include the namespace identifier for every element in your query. With this slight adjustment, your code works:
var usernames = from r in doc.Descendants(ns + "Credential")
select r.Element(ns + "Username").Value;