1

I am very new to C#, but it seems as though this should be pretty straight forward. I am trying to parse an XML string returned from a web feed that looks like this:

<autnresponse xmlns:autn="http://schemas.autonomy.com/aci/">
  <action>QUERY</action>
  <response>SUCCESS</response>
  <responsedata>
    <autn:numhits>6</autn:numhits>
    <autn:hit>
      <autn:reference>http://something.what.com/index.php?title=DPM</autn:reference>
      <autn:id>548166</autn:id>
      <autn:section>0</autn:section>
      <autn:weight>87.44</autn:weight>
      <autn:links>Castlmania,POUCH</autn:links>
      <autn:database>Postgres</autn:database>
      <autn:title>A Pouch and Mail - Castlmania</autn:title>
      <autn:content>
        <DOCUMENT>
          <DRETITLE>Castlmania Pouch and Mail - Castlmania</DRETITLE>
          <DRECONTENT>A paragraph of sorts that would contain content</DRECONTENT>
        </DOCUMENT>
      </autn:content>
  </autn:hit>
  <autn:hit>...</autn:hit>
  <autn:hit>...</autn:hit>
  <autn:hit>...</autn:hit>
  <autn:hit>...</autn:hit>
</autnresponse>

with no luck. I am using this code to start:

XmlDocument xmlString = new XmlDocument();
xmlString.LoadXml(xmlUrl);

XmlElement root = xmlString.DocumentElement;
XmlNode GeneralInformationNode =
root.SelectSingleNode("//autnresponse/responsedata/autn:hit");

foreach (XmlNode node in GeneralInformationNode)
{
  Console.Write("reference: "+node["autn:reference"]+" Title:"+node["DRETITLE"]+"<br />);
}

And I would like to print the DRETITLE and autn:reference element of within each of the autn:hit elements. Is that even doable with my approach?

I have tried looking and several example on the good old web like this to no avail.

The error that comes back is:

System.Xml.XPath.XpathEception {NameSpace Manager or XsltContext needed. ...}

Thanks in advance.

UPDATE:

In trying to use XmlNamespaceManager, one has to give it a url to the schema definition like so:

XmlNamespaceManager namespmng = new XmlNamespaceManager (xmlString.NameTable);
namespmng.AddNamespace("autn","http://someURL.com/XMLschema");

The problem seems to be that now the error is gone, but the data is not displaying. I should mention that I am working off of a machine that does not have internet connectivity. The other thing is the schema seems to be unavailable. I am guessing that XmlNamespaceManager would work once able to connect to the internet right?

2
  • Looks like a dup of XmlDocument.SelectSingleNode and xmlNamespace issue. Commented Jul 22, 2016 at 19:10
  • Similar but quite different in the sense that they are trying to improve how they are returning an element. I am trying to return nested elements within a loop. Commented Jul 22, 2016 at 19:33

2 Answers 2

3

Using System.Xml.Linq it could be something like this:

var doc = XElement.Load(xmlUrl);
var ns = doc.GetNamespaceOfPrefix("autn");

foreach (var hit in doc.Descendants(ns + "hit"))
{
   var reference = hit.Element(ns + "reference").Value;
   var dretitle = hit.Descendants("DRETITLE").Single().Value;
   WriteLine($"ref: {reference} title: {dretitle}");
}
Sign up to request clarification or add additional context in comments.

1 Comment

This was the money shot! Thanks so much.
2

Firstly, the exception you're getting is because you haven't loaded the namespace using the XmlNamespaceManager for the xml you're parsing. Something like this:

XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xmlString.NameTable);
if (root.Attributes["xmlns:autn"] != null)
{
    uri = root.Attributes["xmlns:autn"].Value;
    namespaceManager.AddNamespace("autn", uri);
} 

Secondly, what you're trying to do is possible. I'd suggest using root.SelectNodes(<your xpath here>) which will return a collection of autn:hit nodes that you can loop through instead of SelectSingleNode which will return one node. Within that you can drill down to the content/DOCUMENT/DRETITLE and pull the text for the DRETITLE node using either XmlNode.Value if you select the text specifically or XmlNode.InnerText on the DRETITLE node.

3 Comments

Can you elaborate on root.SelectNodes syntax and how that might look?
This approach does not seem to work with the URI is not available.
If you can't reach your namespace you'll have to add the namespace prefix in your xpath queries for each element as they are for the nodes. SelectNodes syntax should be similar to what you did for SelectSingleNode. It'll return a list of nodes you can loop through using a foreach. To get the specific value you can select the node (via selectsinglenode using xpath) that contains the value you want.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.