I'm trying to get all the entry elements so I can display them, haven't done Xpath for a while but I thought it would be fairly simple heres what I have so far - rssNodes count is 0, what am I missing?
XmlDocument rssXmlDoc = new XmlDocument();
rssXmlDoc.Load("http://www.businessopportunities.ukti.gov.uk/alertfeed/1425362.rss");
var rssNodes = rssXmlDoc.SelectNodes("feed/entry");
The XML file has the following structure:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<!-- some other child elements -->
<entry>
<!-- child elements -->
</entry>
<entry>
<!-- child elements -->
</entry>
<!-- more entry elements -->
<!-- some other child elements -->
</feed>
You need to properly use namespaces:
var nsm = new XmlNamespaceManager(rssXmlDoc.NameTable);
nsm.AddNamespace("atom", "http://www.w3.org/2005/Atom");
var entries = rssXmlDoc.SelectNodes("/atom:feed/atom:entry", nsm);
You need to respect XML namespaces with XPath.
NOTE: If the namespace of the entry element is known, see JLRishe's answer which is more elegant in that case.
If you don't know the XML namespace beforehand you can also ignore it using the XPath built-in local-name() function:
SelectNodes("//*[local-name()='entry']")
This will get all entry elements in the entire XML document, no matter which namespace the element belongs to.
Related
This question already has answers here:
Adding a prefix to an xml node
(2 answers)
Rewrite XMLDocument to use namespace prefix
(3 answers)
Closed 2 years ago.
I need to create XML like below. Because of retardation of target system. I need to have prefixes in front of all nodes. All nodes need to have "ns0" prefix present.
<?xml version="1.0" encoding="utf-8"?>
<ns0:RootElement xmlns:ns0="http://top-secret">
<ns0:MainMessage>
<ns0:Date>1</ns0:Date>
<ns0:Field1>2</ns0:Field1>
<ns0:Field2>3</ns0:Field2>
</ns0:MainMessage>
</ns0:RootElement>
There is no schema. I need to add nodes depending on user input. This is sample of the code that add nodes to "ns0:MainMessage" element:
XmlDocument xml = new XmlDocument();
xml.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><ns0:RootElement xmlns:ns0=\"http://top-secret\"><ns0:MainMessage></ns0:MainMessage></ns0:RootElement>");
XmlElement mainMessageElement = xml.DocumentElement["ns0:MainMessage"];
XmlElement newElement = mainMessageElement.OwnerDocument.CreateElement("Date");
newElement.Prefix = "ns0";
newElement.InnerText = "thisIsTest;
mainMessageElement.AppendChild(newElement);
This produces output like this:
<?xml version="1.0" encoding="utf-8"?>
<ns0:RootElement xmlns:ns0="http://top-secret">
<ns0:MainMessage>
<Date>thisIsTest</Date>
</ns0:MainMessage>
</ns0:RootElement>
While I need output where "Date" element is prefixed with "ns0" like "ns0:Date". Like so:
<?xml version="1.0" encoding="utf-8"?>
<ns0:RootElement xmlns:ns0="http://top-secret">
<ns0:MainMessage>
<ns0:Date>thisIsTest</ns0:Date>
</ns0:MainMessage>
</ns0:RootElement>
How to force this Date element to have ns0 prefix?
You need to actually qualify the element into the correct namespace:
var newElement = mainMessageElement.OwnerDocument.CreateElement(
"Date", "http://top-secret");
newElement.Prefix = "ns0";
Note, however, that it may be easier to do all of this with the XDocument API.
I have the following XML structure:
<?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<StoreResponse xmlns="http://www.some-site.com">
<StoreResult>
<Message />
<Code>OK</Code>
</StoreResult>
</StoreResponse>
</soap:Body>
</soap:Envelope>
I need to get the InnerText from Codeout of this document and I need help with the appropriate XPATH statement.
I'm really confused by XML namespaces. While working on a previous namespace problem in another XML document, I learned, that even if there's nothing in front of Code (e.g. ns:Code), it is still part of a namespace defined by the xmlns attribute in its parent node. Now, there are multiple xmlns nodes defined in parents of Code. What is the namespace that I need to specify in an XPATH statement? Is there such a thing as a "primary namespace"? Do childnodes inherit the (primary) namespace of it's parents?
The namespace of the <Code> element is http://www.some-site.com. xmlsn:xxx means that names prefixed by xxx: (like soap:Body) have that namespace. xmlns by itself means that this is the default namespace for names without any prefix.
An example of using an XDocument (Linq) approach:
XNamespace ns = "http://www.some-site.com";
var document = XDocument.Parse("your-xml-string");
var elements = document.Descendants( ns + "StoreResult" )
Descendant elements will inherit the last immediate namespace. In your example you will need to create two namespaces one for the soap envelope and a second for "some-site".
Here's an option I found in this question: Weirdness with XDocument, XPath and namespaces
var xml = "<your xml>";
var doc = XDocument.Parse(xml); // Could use .Load() here too
var code = doc.XPathSelectElement("//*[local-name()='Code']");
I have a xml where i want to select a node from it here is the xml:
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<InResponse xmlns="https://ww.ggg.com">
<InResult>Error </InResult>
</InResponse>
</soap:Body>
</soap:Envelope>
I am loading it using XmlDocument's LoadXML and trying to get InResult node but I get null see below please:
xml.SelectSingleNode("//InResult").InnerText;
You have a namespace declaration and you should add this into your XPath or you can use namespace agnostic XPath. Try next code as namespace agnostic solution:
xml.SelectSingleNode("//*[local-name()='InResult']").InnerText;
I've received Error as result
From http://www.w3schools.com/ site:
local-name() - Returns the name of the current node or the first node
in the specified node set - without the namespace prefix
You can get more information about XPath functions here.
Namespace aware solution, is given below:
var namespaceManager = new XmlNamespaceManager(x.NameTable);
namespaceManager.AddNamespace("defaultNS", "https://ww.ggg.com");
var result = x.SelectSingleNode("//defaultNS:InResponse", namespaceManager).InnerText;
Console.WriteLine (result); //prints Error
Brief XML notes:
This part in root note xmlns:soap="http://www.w3.org/2003/05/soap-envelope" is a xml namespace declaration. It is used to identify nodes in your xml structure. As a rule, you need to specify them to access nodes with it, but there are namespace agnostic solutions in XPath and in LINQ to XML. Now if you see node name as <soap:Body>, this means, that this node belongs to this namespace.
This seems to be an namespace issue
You can use an XmlNamespaceManager before you call SelectSingleNode():
XmlNamespaceManager ns = new XmlNamespaceManager(xmldoc.NameTable);
ns.AddNamespace("ggg", "https://ww.ggg.com");
xml.SelectSingleNode("//ggg:InResult", ns).InnerText;
Attention: Not tested.
Fairly simple one, but my knowledge is limited in this area. I'm using the following c# code to access the value of elements within my SGML and XML documents.
It's working fine when there is only one element with the given name in the document, but as soon as there are more than one element with the same name it throws an exception, obviously!
I need to use xpath or some other way of specifying the location of the element i'm trying to get the value of.
XDocument doc = XDocument.Load(sgmlReader);
string system = doc.Descendants("chapnum").Single().Value;
return system;
This works fine, if there is only one "chapnum" in the doc, but i need to specifically get the value of "chapnum" at the following nested location "dmaddres/chapnum".
How please?
Here is a sample of the xml doc. I'm trying to get the value of the "chapnum" element nested in the "dmaddress" element.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dmodule []>
<dmodule xmlns:dc="http://www.purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.s1000d.org/S1000D_2-3-1/xml_schema_flat/descript.xsd">
<idstatus>
<dmaddres>
<dmc><avee><modelic>xx</modelic><sdc>A</sdc><chapnum>29</chapnum>
<section>1</section><subsect>3</subsect><subject>54</subject><discode
>00</discode><discodev>AAA</discodev><incode>042</incode><incodev
>A</incodev><itemloc>D</itemloc></avee></dmc>
<dmtitle><techname>Switch</techname><infoname>Description of function</infoname>
</dmtitle>
<issno inwork="00" issno="001" type="new"/>
<issdate day="20" month="07" year="2012"/>
<language language="sx"/></dmaddres>
<status>
<security class="01"/><datarest><instruct><distrib>-</distrib><expcont
>Obey the national regulations for export control.</expcont></instruct>
<inform><copyright><para><refdm><avee><modelic>xx</modelic><sdc>A</sdc>
<chapnum>29</chapnum><section>1</section><subsect>3</subsect><subject
>54</subject><discode>00</discode><discodev>ZZZ</discodev><incode
>021</incode><incodev>Z</incodev><itemloc>D</itemloc></avee></refdm
></para></copyright><datacond>BREXREF=AJ-A-00-00-00-05ZZZ-022Z-D VERSUB=CDIM-V6</datacond>
</inform></datarest>
<rpc>xxxxx</rpc>
<orig>xxxxx</orig>
<applic>
<type>-</type>
<model model="xxxxx"><mfc>xxxxx</mfc><pnr>xxxxxxx</pnr></model>
</applic>
<brexref><refdm><avee><modelic>xx</modelic><sdc>A</sdc><chapnum>00</chapnum>
<section>0</section><subsect>0</subsect><subject>00</subject><discode
>05</discode><discodev>ZZZ</discodev><incode>022</incode><incodev
>Z</incodev><itemloc>D</itemloc></avee></refdm></brexref>
like this?
string system = doc.Descendants("dmaddres")
.Single(e => e.Element("chapnum") != null)
.Element("chapnum").Value;
string system = doc.Root.Element("dmaddres").Element("chapnum").Value;
would probably do just as well.
I have a complex XML file with structure as follows:
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="xxx:xxx:xxx:xxx:xxxxx:xxx:xsd:xxxx.xxx.xxx.xx">
<Element1>
<Element2>
<Element2A>xxxxxx</Element2A>
<Element2B>2012-08-29T00:00:00</Element2B>
</Element2>
</Element1>
</Document>
Now I am using XmlReader to read this XML document and process information as follows
XmlReader xr = XmlReader.Create(filename);
while (xr.Read())
{
xr.MoveToElement();
XElement node = (XElement)XElement.ReadFrom(xr);
Console.WriteLine(node.Name);
}
xr.Close();
The problem I am facing is in the output the namespace is prefixed to the ElementName. E.g output
{xxx:xxx:xxx:xxx:xxxxx:xxx:xsd:xxxx.xxx.xxx.xx}Element1
Is there any way I can remove/ handle this as I need to do further filtering using Element names and Child names.
XElement.Name is not (as you might expect) a String, but rather an XName which has a LocalName property, thus:
Console.WriteLine(node.Name.LocalName);
You may want to remove the namespace. One way to remove namespace is to write c# code and other way is to use XSLT transformation as suggested in Remove Namespace
-Milind