Kirill
Kirill

Reputation: 37

c# SelectSingleNode in xml returns null. There is no similar resolutions this issue at this site

I've got the problem with reading XML string. Here I've got the following one:

<SplitterLayoutDataSet xmlns="http://tempuri.org/SplitterLayoutDataSet.xsd"> 
    <SplitterLayout> 
        <SplitterName>mainSplitContainerControl</SplitterName> 
            <SplitterPosition>0.2213375796178344</SplitterPosition> 
     </SplitterLayout> 
</SplitterLayoutDataSet>

So, I want to read <SplitterName> tag wih the following code:

XmlElement rootElement = doc.DocumentElement;
rootElement.RemoveAllAttributes();
if (rootElement != null)
    {
        foreach (KeyValuePair<Control, object> key in SaveLayoutControls)
        {
            Control c = key.Key;
            XmlElement el = rootElement.SelectSingleNode("SplitterName") as XmlElement;
            if (el != null)
            {
                if (c is GridControl)
                    SetGridLayout(el, c as GridControl);
                else if (c is SplitContainerControl)
                    SetSplitContainerLayout(el, c as SplitContainerControl);
                else if (c is TreeList)
                    SetTreeListLayout(el, c as TreeList);
                else if (c is CollapsibleSplitter)
                    SetCollapsibleSplitterLayout(el, c as CollapsibleSplitter);
                else if (c is Splitter)
                    SetSplitterLayout(el, c as Splitter);
                }
            }
       }

I want to read the "el" field, but it returns me NULL value. Are there any ideas to resolve this issue? Because I tried many ways and had no result. Thanks

Upvotes: 1

Views: 817

Answers (3)

Kirill
Kirill

Reputation: 37

OK, I found a solution. I tried to use namespaces, now this part of code works OK. Here is the following sample of code;

    XmlDocument doc = new XmlDocument();
    doc.InnerXml = xml;
    XmlElement rootElement = doc.DocumentElement as XmlElement;
    XmlNamespaceManager xns = new XmlNamespaceManager(doc.NameTable);
    xns.AddNamespace("ns", "http://tempuri.org/SplitterLayoutDataSet.xsd");
    if (rootElement != null)
    {
        foreach (KeyValuePair<Control, object> key in SaveLayoutControls)
        {
            Control c = key.Key;
            XmlElement el = rootElement.SelectSingleNode("ns:SplitterLayout", xns) as XmlElement;
            if (el != null)
            {
                if (c is GridControl)
                    SetGridLayout(el, c as GridControl);
                else if (c is SplitContainerControl)
                    SetSplitContainerLayout(el, c as SplitContainerControl);
                else if (c is TreeList)
                    SetTreeListLayout(el, c as TreeList);
                else if (c is CollapsibleSplitter)
                    SetCollapsibleSplitterLayout(el, c as CollapsibleSplitter);
                else if (c is Splitter)
                    SetSplitterLayout(el, c as Splitter);
            }
        }
    }

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500515

There are two problems:

1) You're asking for a SplitterName element without a namespace whereas the one in your XML file implicitly uses the namespace URI "http://tempuri.org/SplitterLayoutDataSet.xsd".

2) You're asking for a node directly under the document element, and your SplitterName element isn't a direct child of SplitterLayoutDataSet.

You definitely can use XPath for this using XmlNamespaceManager, but personally I'd try to use LINQ to XML:

XNamespace ns = "http://tempuri.org/SplitterLayoutDataSet.xsd";
XElement root = ...;
XElement names = root.Descendants(ns + "SplitterName").First();

(Additionally, it's not clear why you're searching for that element on every iteration, when you're not using key anywhere in the search...)

Upvotes: 2

Sten Petrov
Sten Petrov

Reputation: 11040

Your XPath doesn't point to the right place.

"SplitterName" xpath would check for that element under the root element.

Use

"//SplitterName" or "//SplitterLayout/SplitterName" or "\SplitterLayoutDataSet/SplitterLayout/SplitterName"

AND remove the xmlns="zzz" or add NamespaceManager to the query with the namespace added and the XPath elements prefixed, such as "//ns:SplitterName"

Upvotes: 0

Related Questions