.Net SelectSingleNode() problems

Lars_Westman
Member Posts: 116
I have started the move from COM to .Net in a solution which involves sending a webservice request and receiving and getting data out of the response. The request and getting the XML data back into an variable of the type System.Xml.XmlDocument.System.Xml is no problem (lets call this variable for "XMLDoc" here). I can also use XMLDoc.GetElementsByTagName('NodeName') to navigate to a set of nodes to loop through. My problem starts when I want to get values from child nodes.
Example of XML:
With COM i could do like this to get the value from the node called 'Result':
This would give a message box saying "Saved" with the XML sample data above. But with .Net variables "SelectSingleNode" does not return anything. I think it has something to do with the namespace which suddenly seems to have become important. I just haven't figured how to deal with it yet so any help would be great. ](*,)
Another common thing I often do with the xml data is to loop through instances of nodes such as the "ReqResult" above. Then I use CurrNode := CurrNodeList.item(0..n) in a FOR loop and want to pick values from the child nodes. This is easy with COM but of course I get the same problem as in my example above.
Any hint in the right direction is appreciated
Edit: I got the solution for this in an email just after I posted this \:D/
The trick is to assign a NamspaceManager variable. The variable is of the type System.Xml.XmlNamespaceManager.System.Xml. Lets call it "NsMgr". When the XMLDoc is loaded these two lines of code is needed to assign NsMgr based on the XML example above:
Example of XML:
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <ReqResponse xmlns="http://services.thedomain.info/the.appname.v3"> <ReqResult> <Result>Saved</Result> <Number>6609403768</Number> <Id>0114</Id> <Details> <Detail> <Number>373400306320689675</Number> </Detail> <Detail> <Number>373400306320689859</Number> </Detail> </Details> </ReqResult> </ReqResponse> </soap:Body> </soap:Envelope>
With COM i could do like this to get the value from the node called 'Result':
CurrNodeList := XMLDoc.getElementsByTagName(ResponseText); CurrNode := CurrNodeList.item(0); CurrNode2 := CurrNode.selectSingleNode('Result'); MESSAGE(CurrNode2.text);
This would give a message box saying "Saved" with the XML sample data above. But with .Net variables "SelectSingleNode" does not return anything. I think it has something to do with the namespace which suddenly seems to have become important. I just haven't figured how to deal with it yet so any help would be great. ](*,)
Another common thing I often do with the xml data is to loop through instances of nodes such as the "ReqResult" above. Then I use CurrNode := CurrNodeList.item(0..n) in a FOR loop and want to pick values from the child nodes. This is easy with COM but of course I get the same problem as in my example above.
Any hint in the right direction is appreciated

Edit: I got the solution for this in an email just after I posted this \:D/
The trick is to assign a NamspaceManager variable. The variable is of the type System.Xml.XmlNamespaceManager.System.Xml. Lets call it "NsMgr". When the XMLDoc is loaded these two lines of code is needed to assign NsMgr based on the XML example above:
NsMgr := NsMgr.XmlNamespaceManager(XMLDoc.NameTable); NsMgr.AddNamespace('ns', 'http://services.thedomain.info/the.appname.v3');And the node is found with:
CurrNode2 := CurrNode.SelectSingleNode('ns:Result');//Lars
Lars Westman
http://www.linkedin.com/in/larswestman
http://www.linkedin.com/in/larswestman
0
Answers
-
Thx, again a topic which should me moved to tips.
You showed the code snippet with COM
Could you show the full code snippet with .NET too?0 -
mdPartnerNL wrote:....Could you show the full code snippet with .NET too?
It was already there in the post, but I have set code tags on it now.Lars Westman
http://www.linkedin.com/in/larswestman0 -
I am stuck. I did similar to what you are doing, but still could not get the SelectSingleNode to work. SelectSingleNode will work as long as there are no XMLNS definition in the file. But once there is xmlns definition, then it will not work.
Name DataType Subtype Length XMLDoc DotNet System.Xml.XmlDocument.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Node DotNet System.Xml.XmlNode.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Node2 DotNet System.Xml.XmlNode.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' NameSpaceMgr DotNet System.Xml.XmlNamespaceManager.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' FileName Text 250 FileMgmt Codeunit File Management f File FileInStream InStream CLEARALL(); XMLDoc := XMLDoc.XmlDocument; FileName := 'c:\temp\temp1.xml'; FileName := FileMgmt.UploadFileSilent(FileName); IF NOT EXISTS(FileName) THEN EXIT; f.OPEN(FileName); f.TEXTMODE(TRUE); f.CREATEINSTREAM(FileInStream); XMLDoc.Load(FileInStream); Node := XMLDoc.DocumentElement; NameSpaceMgr := NameSpaceMgr.XmlNamespaceManager(XMLDoc.NameTable); NameSpaceMgr.AddNamespace('urn', 'oasis:names:specification:ubl:schema:xsd:Invoice-2'); Node2 := Node.SelectSingleNode('invoice', NameSpaceMgr); MESSAGE(Node2.InnerText); // error here
The XML File:<content xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"> <invoice> <id>inv_001</id> <name>user name</name> </invoice> </content>
0 -
You cannot select "invoic" directly, as it is part of the parent namespace. The correct way to select it is to use the namespace name followed by ':' and then the tag name.
Like it is shown in the first post of this topic:CurrNode2 := CurrNode.SelectSingleNode('ns:Result');
So, for your example, you will have to define the namespace manager as following:NameSpaceMgr.AddNamespace('ns', 'urn:oasis:names:specification:ubl:schema:xsd:Invoice-2');
and select the node by using:Node2 := Node.SelectSingleNode('ns:invoice', NameSpaceMgr);
I hope it will work, I haven't tested it.0 -
Yes. it works now. So, that means empty name spaces, have to be explicitly added into NameSpaceManager as "ns".
Anyway my complete solution below:
What it does is that it will auto add all name spaces.
XML File:<content xmlns="dummyxyz" xmlns:abc="dummy123" xmlns:def="dummy456"> <invoice> <id>inv_001</id> <abc:name>user name</abc:name> <def:name>user name</def:name> </invoice> </content>
Variables:Name DataType Subtype Length XMLDoc DotNet System.Xml.XmlDocument.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Node1 DotNet System.Xml.XmlNode.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Node2 DotNet System.Xml.XmlNode.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Node3 DotNet System.Xml.XmlNode.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' NameSpaceMgr DotNet System.Xml.XmlNamespaceManager.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' XPathNavigator DotNet System.Xml.XPath.XPathNavigator.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' IDicEnum DotNet System.Collections.Generic.SortedDictionary`2+Enumerator.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' IDic DotNet System.Collections.Generic.SortedDictionary`2.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' IDicKeys DotNet System.Collections.Generic.SortedDictionary`2+KeyCollection.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' IDicValues DotNet System.Collections.Generic.SortedDictionary`2+ValueCollection.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' IDicKeysEnum DotNet System.Collections.Generic.SortedDictionary`2+KeyCollection+Enumerator.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' IDicValuesEnum DotNet System.Collections.Generic.SortedDictionary`2+ValueCollection+Enumerator.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' XMLNameSpaceScope DotNet System.Xml.XmlNamespaceScope.'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' FileName Text 250 FileMgmt Codeunit File Management f File FileInStream InStream
Code:CLEARALL(); XMLDoc := XMLDoc.XmlDocument; FileName := 'c:\temp\temp1.xml'; FileName := FileMgmt.UploadFileSilent(FileName); IF NOT EXISTS(FileName) THEN EXIT; f.OPEN(FileName); f.TEXTMODE(TRUE); f.CREATEINSTREAM(FileInStream); XMLDoc.Load(FileInStream); Node1 := XMLDoc.DocumentElement; NameSpaceMgr := NameSpaceMgr.XmlNamespaceManager(XMLDoc.NameTable); XPathNavigator := Node1.CreateNavigator; IDic := XPathNavigator.GetNamespacesInScope(XMLNameSpaceScope.All); IDicKeys := IDic.Keys; IDicValues := IDic.Values; IDicKeysEnum := IDicKeys.GetEnumerator; IDicValuesEnum := IDicValues.GetEnumerator; WHILE IDicKeysEnum.MoveNext DO BEGIN IDicKeys := IDicKeysEnum.Current; IDicValuesEnum.MoveNext; IDicValues := IDicValuesEnum.Current; IF FORMAT(IDicKeys.ToString) <> '' THEN NameSpaceMgr.AddNamespace(IDicKeys.ToString, IDicValues.ToString) ELSE NameSpaceMgr.AddNamespace('ns', IDicValues.ToString); END; Node1 := XMLDoc.DocumentElement; MESSAGE(Node1.Name + '-' + Node1.InnerText); Node2 := Node1.SelectSingleNode('ns:invoice', NameSpaceMgr); MESSAGE(Node2.Name + '-' + Node2.InnerText); Node3 := Node2.SelectSingleNode('ns:id', NameSpaceMgr); MESSAGE(Node3.Name + '-' + Node3.InnerText); Node3 := Node2.SelectSingleNode('abc:name', NameSpaceMgr); MESSAGE(Node3.Name + '-' + Node3.InnerText); Node3 := Node2.SelectSingleNode('def:name', NameSpaceMgr); MESSAGE(Node3.Name + '-' + Node3.InnerText);
0
Categories
- All Categories
- 73 General
- 73 Announcements
- 66.6K Microsoft Dynamics NAV
- 18.7K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 617 NAV Courses, Exams & Certification
- 2K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 320 Dynamics CRM
- 111 Dynamics GP
- 10 Dynamics SL
- 1.5K Other
- 990 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 35 Design Patterns (General & Best Practices)
- 1 Architectural Patterns
- 10 Design Patterns
- 5 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1.1K General Chat
- 1.6K Website
- 83 Testing
- 1.2K Download section
- 23 How Tos section
- 252 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions