Using InfoPath lately has really made me sharpen up my knowledge of working
with Xml such as querying it with XPath.
Prior to the last week or so, all of the Xml that I've queried has been
non-namespaced. Adding namespaces
to Xml documents and nodes means that you need to set some attributes on the
underlying namespace manager of the XmlDocument when you need to query it using
XPath. In C# this would look
similar to this:
1XmlDocument xml = new XmlDocument() ;
2xml.Load(@"C:\Temp\Groups.xml") ;
3XmlNamespaceManager mgr = new XmlNamespaceManager(xml.NameTable) ;
4
5// ADD THE NAMESPACE
6mgr.AddNamespace("tns", @"http://MarkItUp.com/ProjectDistributor/WebServices/ProjectDistributor") ;
7// SO THAT I CAN USE IT IN THIS QUERY
8XmlNodeList nodes = xml.SelectNodes(@"//tns:Group", mgr) ;
9
10mgr = new XmlNamespaceManager(xml.NameTable) ;
11// ADD THE NAMESPACE
12mgr.AddNamespace("tns", @"http://MarkItUp.com/ProjectDistributor/WebServices/ProjectDistributor") ;
13
14for (int i=0; i<nodes.Count; i++) {
15 // SO THAT I CAN USE IT IN THIS QUERY
16 Console.WriteLine(nodes[i].SelectSingleNode("tns:DisplayName", mgr).InnerText) ;
There is a similar syntax when querying xml documents from within
javascript queries in InfoPath - such as when you have javascript in a custom
task pane although the syntax is slightly different. Here is the
javascript version of the above code:
1var ns2 = "xmlns:tns='http://MarkItUp.com/ProjectDistributor/WebServices/ProjectDistributor'";
2
3myXmlDoc.setProperty("SelectionNamespaces", ns2);
4var nodes = myXmlDoc.selectNodes("//tns:Group") ;
5
6for (var i=0; i<nodes.length; i++) {
7 s += 'Group: ' + nodes[i].selectSingleNode("tns:DisplayName").text ;
8}
9document.getElementById("groupsDIV").innerHTML = s ;
As you can see, you need to get the setProperty code right
and also transpose the correct xmlns namespace
information. Today I wrote a little console tool which allows you to load
the xml from an InfoPath form, enter the name of the node that you are looking
for and it will return the correct syntax for creating the selection namespace
code and querying the value from that node. Here is the output after
loading an xml document with a node named my:txtUsername:
1XDocument.DOM.setProperty("SelectionNamespaces",
2 'xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2004-12-17T00-31-40"')
3var str = XDocument.DOM.selectSingleNode("//my:txtUsername")
This is a dirt simple tool - I wrote it on the bus on the way to work :-)
but, I've uploaded it my ProjectDistributor account and it is available
from here:
Project
Distributor :: MarkItUp ::
InfoPathXmlParser
:: 1.0.0.0
Future plans will be to create a webpage which provides a simple UI for
running that tool without having to have it on your own system. What would
be nice is, after loading the xml, I should display it in a TreeView and allow
the user to click on nodes and retrieve the code that way instead of having to
type in a raw node name.