SelectSingleNode() function returns null
-
Tuesday, June 17, 2008 11:59 AM
I am developing a program for reading RDL files (Reporting Services Report Files). Assume my XML is the following:
<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
<DataSources>
<DataSource Name="DataSource">
<ConnectionProperties>
<IntegratedSecurity>true</IntegratedSecurity>
<ConnectString></ConnectString>
<DataProvider></DataProvider>
</ConnectionProperties>
<rd
ataSourceID>136c762c-789b-4fa7-b4a8-b60c584c387b</rd
ataSourceID></DataSource>
</DataSources>
<BottomMargin>2.5cm</BottomMargin>
<RightMargin>2.5cm</RightMargin>
<rd
rawGrid>true</rd
rawGrid><InteractiveWidth>8.5in</InteractiveWidth>
<rd:GridSpacing>0.25cm</rd:GridSpacing>
<rd
napToGrid>true</rd
napToGrid>.
.
.
</Report>
When I write the following code to get the "DataSources" Node, the SelectSingleNode() function returns null:
doc.SelectSingleNode("DataSources")
or
doc.DocumentElement.SelectSingleNode("DataSources")
or
doc.SelectSingleNode("//DataSources")
or
doc.DocumentElement.SelectSingleNode("//DataSources")
or
doc.SelectSingleNode("/DataSources")
or
doc.DocumentElement.SelectSingleNode("/DataSources")
why?
Answers
-
Tuesday, June 17, 2008 12:22 PM
There is a default namespace declaration you need to take into account by using an XmlNamespaceManager as follows:
Code SnippetDim doc As New XmlDocument()
doc.Load("file.xml")
Dim mgr As New XmlNamespaceManager(doc.NameTable)
mgr.AddNamespace("df", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition")
Dim node As XmlNode = doc.SelectSingleNode("/df:Report/df:DataSources", mgr)
-
Tuesday, July 08, 2008 4:22 PM
That element is down in the document so you either need to give the full path or you need to use // in your XPath e.g.
Code Snippet//ACORD:InsuranceSvcRq
The full path looks like
Code Snippet/ACORD:ACORD/ACORD:InsuranceSvcRq
As a third alternative, as you call SelectSingleNode on the DocumentElement (my sample calls it on the document node), you could use
ACORD:InsuranceSvcRq
without a leading slash.
All Replies
-
Tuesday, June 17, 2008 12:22 PM
There is a default namespace declaration you need to take into account by using an XmlNamespaceManager as follows:
Code SnippetDim doc As New XmlDocument()
doc.Load("file.xml")
Dim mgr As New XmlNamespaceManager(doc.NameTable)
mgr.AddNamespace("df", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition")
Dim node As XmlNode = doc.SelectSingleNode("/df:Report/df:DataSources", mgr)
-
Tuesday, July 08, 2008 4:11 PM
I am still having the problem with this method returning null. I've recreated Martin's example.
My XML is below:Code Snippet<?
xml version="1.0" encoding="utf-8"?><
ACORD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.ACORD.org/standards/PC_Surety/ACORD1.4.1/xml/"><
SignonRq><
ClientApp><
Org>Online</Org></
ClientApp></
SignonRq><
InsuranceSvcRq><
RqUID>00000000-0000-0000-0000-001030582207</RqUID><
PersAutoPolicyQuoteInqRq><
RqUID>00000000-0000-0000-0000-001030582207</RqUID><
PersPolicy><
ContractTerm><
EffectiveDt>2008-07-08</EffectiveDt></
ContractTerm></
PersPolicy></
PersAutoPolicyQuoteInqRq></
InsuranceSvcRq></
ACORD>And my code, which throws an exception every time:
Code Snippetstatic void Main(string[] args){
XmlDocument doc = new XmlDocument();doc.Load(
"my.xml"); XmlNamespaceManager xnm = new XmlNamespaceManager(doc.NameTable);xnm.AddNamespace(
"ACORD", "http://www.ACORD.org/standards/PC_Surety/ACORD1.4.1/xml/"); XmlNode node = doc.DocumentElement.SelectSingleNode("/ACORD:InsuranceSvcRq", xnm); if (node == null) throw new NullReferenceException();}
-
Tuesday, July 08, 2008 4:22 PM
That element is down in the document so you either need to give the full path or you need to use // in your XPath e.g.
Code Snippet//ACORD:InsuranceSvcRq
The full path looks like
Code Snippet/ACORD:ACORD/ACORD:InsuranceSvcRq
As a third alternative, as you call SelectSingleNode on the DocumentElement (my sample calls it on the document node), you could use
ACORD:InsuranceSvcRq
without a leading slash.
-
Tuesday, July 08, 2008 4:44 PM
Outstanding - that works great! I found this notation to be the most helpful:
Code Snippet//ACORD:InsuranceSvcRq
Because it simply searches for that element, you don't have to specify the full path. Thanks for your help.
-
Tuesday, July 08, 2008 4:51 PM
But note that using // is expensive as it searches through the whole document. It does not matter for small documents but if you have large documents you might want to avoid using // in your XPath expressions if you can write a more precise XPath expression.

