Ian Vink
Ian Vink

Reputation: 68770

XPath: Selecting a child from an XElement in C#

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
    <meta name="Generator"/>
  </head>
  <body>
    <h1>My head 1</h1>
  </body>
</html>

This above is the .ToString of my XElement object , html. Looks good.

I am trying to get the body's innerXml but my XPath returns null.

XElement html = GettheHTMLAsXElementCorrectly()
var whyIsThisNull =  html.XPathSelectElement("/html/body");

Upvotes: 0

Views: 2182

Answers (2)

CodeZombie
CodeZombie

Reputation: 5377

Whenever namespaces are used (in your case in the <html>) you need to define the namespace when searching for nodes:

Using LINQ to XML
(In my opinion the easier and cleaner solution)

// Create a XNamespace instance for the default namespace
XNamespace xhtml = "http://www.w3.org/1999/xhtml";

// Select the node using LINQ to XML
var bodyByLinq = doc.Element(xhtml + "html").Element(xhtml + "body");

Using XPath

// Create a namespace manager
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());

// Define your default namespace including a prefix to be used later in the XPath expression
namespaceManager.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");

// Select the node using XPath
var bodyByXPath = doc.XPathSelectElement("/xhtml:html/xhtml:body", namespaceManager);

Update: Improved my answer as the example provided was not correct

Upvotes: 3

Ian Vink
Ian Vink

Reputation: 68770

@zombiehunter is correct so I gave him the credit.

I tried this way as well, I just told the XPath is ignore the namespace. Seems to also work.

var notNullAnyMore =  html.XPathSelectElement("//*[local-name() = 'body']" );

Upvotes: 0

Related Questions