XmlDocument.SelectNodes does not behave properly with some Xpath expressions

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

The method XmlDocument.SelectNodes does not behave properly in some situations

Here is the XML file with which the behavior reproduces

<VisualStudioProject><CSHAR
ProjectType = "Local
ProductVersion = "7.10.3077
SchemaVersion = "2.0
ProjectGuid = "{3CE6E417-5F92-42F9-A5F2-8710F577D686}
<Build><Setting
ApplicationIcon = "App.ico
AssemblyKeyContainerName = "
AssemblyName = "ResxWrapWizard
AssemblyOriginatorKeyFile = "
DefaultClientScript = "JScript
DefaultHTMLPageLayout = "Grid
DefaultTargetSchema = "IE50
DelaySign = "false
OutputType = "WinExe
PreBuildEvent = "
PostBuildEvent = "
RootNamespace = "ResxWrapWizard
RunPostBuildEvent = "OnBuildSuccess
StartupObject = "
Name = "Debug
AllowUnsafeBlocks = "false
BaseAddress = "285212672
CheckForOverflowUnderflow = "false
ConfigurationOverrideFile = "
DefineConstants = "DEBUG;TRACE
DocumentationFile = "
DebugSymbols = "true
FileAlignment = "4096
IncrementalBuild = "false
NoStdLib = "false
NoWarn = "
Optimize = "false
OutputPath = "bin\Debug\
RegisterForComInterop = "false
RemoveIntegerChecks = "false
TreatWarningsAsErrors = "false
WarningLevel = "4
/><Confi
Name = "Release
AllowUnsafeBlocks = "false
BaseAddress = "285212672
CheckForOverflowUnderflow = "false
ConfigurationOverrideFile = "
DefineConstants = "TRACE
DocumentationFile = "
DebugSymbols = "false
FileAlignment = "4096
IncrementalBuild = "false
NoStdLib = "false
NoWarn = "
Optimize = "true
OutputPath = "bin\Release\
RegisterForComInterop = "false
RemoveIntegerChecks = "false
TreatWarningsAsErrors = "false
WarningLevel = "4
/></Settings><References><Referenc
Name = "System
AssemblyName = "System
HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll
/><Referenc
Name = "System.Data
AssemblyName = "System.Data
HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll
/><Referenc
Name = "System.Drawing
AssemblyName = "System.Drawing
HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Drawing.dll
/><Referenc
Name = "System.Windows.Forms
AssemblyName = "System.Windows.Forms
HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Windows.Forms.dll
/><Referenc
Name = "System.XML
AssemblyName = "System.XML
HintPath = "..\..\..\..\..\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll
/></References></Build><Files><Include><Fil
RelPath = "App.ico
BuildAction = "Content
/><Fil
RelPath = "AssemblyInfo.cs
BuildAction = "Compile
/><Fil
RelPath = "Form1.cs
SubType = "Form"
BuildAction = "Compile"
/><File
RelPath = "Form1.resx"
DependentUpon = "Form1.cs"
BuildAction = "EmbeddedResource"
/></Include></Files></CSHARP></VisualStudioProject>

Here is the code used to return all the nodes from that children of the "/VisualStudioProject/CSHARP/Files/Include":

XmlDocument projSettings = new XmlDocument();
projSettings.Load( "" );
XmlNode root = projSettings.SelectSingleNode( "/VisualStudioProject/CSHARP/Files/Include" );
foreach ( XmlNode sub in root.ChildNodes )
{
Console.WriteLine( sub.Name );
}

But instead of 4 nodes to be returned the following code returns only the very first node.

Also other attempts to retrive the other children nodes with XPath expressions like
XmlDocument.SelectNodes( "//File" ) return only the first node found in the XML file.

At the same time I tried to use the same file through Internet Explorer and query the same XPath expressions through XSLT and everything worked correctly. Thus I think the problem is neither in MS XML Parser nor in XPath expression.

Is there any idea what is wrong?
 
But instead of 4 nodes to be returned the following code returns only
the very first node.

Look at exactly what you're calling:

projSettings.SelectSingleNode

From the documentation for SelectSingleNode:

"Selects the first XmlNode that matches the XPath expression."

so that's behaving exactly as it should. Now:
Also other attempts to retrive the other children nodes with XPath
expressions like XmlDocument.SelectNodes( "//File" ) return only the
first node found in the XML file.

No it doesn't. For instance, having saved the XML you presented as
build.xml, the following program:

using System;
using System.Xml;

public class Test
{
static void Main()
{
XmlDocument projSettings = new XmlDocument();
projSettings.Load( "build.xml" );
XmlNodeList root = projSettings.SelectNodes( "//File");
foreach (XmlNode node in root)
{
Console.WriteLine(node.Attributes["RelPath"].Value);
}
}
}

produces

App.ico
AssemblyInfo.cs
Form1.cs
Form1.resx
 
But instead of 4 nodes to be returned the following code returns onl
Look at exactly what you're calling
projSettings.SelectSingleNod
From the documentation for SelectSingleNode
"Selects the first XmlNode that matches the XPath expression.
so that's behaving exactly as it should.
No, look, I get the root node with the method SelectSingleNode and it returns the node <Include>. This node is the direct parent of the collection of nodes I need. Then I try to use ChildNodes property for retriving the list of nodes I need. But the list contain only 1 element - the very first node.
Here is the code once again
XmlNode root = projSettings.SelectSingleNode( "/VisualStudioProject/CSHARP/Files/Include" )
foreach ( XmlNode sub in root.ChildNodes

Console.WriteLine( sub.Name )


About your sample. It does return only one line for the file as well at my PC. What version of .NET Framework did you test it with? I use v1.1.4322
 
No, look, I get the root node with the method SelectSingleNode and it
returns the node <Include>. This node is the direct parent of the
collection of nodes I need. Then I try to use ChildNodes property for
retriving the list of nodes I need. But the list contain only 1
element - the very first node. Here is the code once again:
XmlNode root = projSettings.SelectSingleNode(
"/VisualStudioProject/CSHARP/Files/Include" );
foreach ( XmlNode sub in root.ChildNodes )
{
Console.WriteLine( sub.Name );
}

About your sample. It does return only one line for the file as well at my PC.
What version of .NET Framework did you test it with? I use v1.1.4322.

I'm using 1.1 as well.

I've just run the above sample, and I get four File lines, not just
one. How sure are you that you're actually loading the right file? If
you just run:

Console.WriteLine (projSettings.OuterXml);

does it do what you expect it to?
 
----- Jon Skeet [C# MVP] wrote: ----

one. How sure are you that you're actually loading the right file? If
you just run
Console.WriteLine (projSettings.OuterXml)
does it do what you expect it to

The mistake was mine. I have mistaken with the folder when I chose the .csproj project file for testing. Now all the methods work. Thank you.
 
Back
Top