Can I create an XmlNamespaceManager object from an XML file that I am going to read?

I have C # code running on sharepoint which I use to check the infopath document inside the xml to check if I should check the document or discard the document.

The code works fine for several different form templates that I created, but it doesn't work on my latested. I found that the generated XmlNamespaceManager contains an invalid definition for the name "MY".

I will try to explain

I have this code for decoding my XmlNamespaceManager

NameTable nt = new NameTable(); NamespaceManager = new XmlNamespaceManager(nt); // Add prefix/namespace pairs to the XmlNamespaceManager. NamespaceManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); NamespaceManager.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml"); NamespaceManager.AddNamespace("dfs", "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"); NamespaceManager.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-07-14T13:45:59"); NamespaceManager.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003");` 

Then I can use the following line of code to search for xml after

 XPathNavigator nav = xml.CreateNavigator().SelectSingleNode("//my:HasSaved", NamespaceManager); 

nav.Value then gets the data I want.

All of this works fine on several of my form templates. I see a new form template and found that I need to use this line instead

 NamespaceManager.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-11-30T17:39:37"); 

The date is different.

My problem is that I cannot add this twice since only one set of forms will work.

So my question. Is there a way that I can generate a NamespaceManager object from an XML file, since all this is contained in the header? I could not find an easy way around this.

+4
source share
3 answers

I found a way to do this. Instead of adding a "my" namespace, you can pull it out of the XmlDocument object. It may just be luck that it works that way, but I'm happy with it.

 NamespaceManager.AddNamespace("my", formXml.DocumentElement.NamespaceURI 

formXML is an XmlDocument created from infopath XML

+4
source

One option is to try loading the xml node using the first namespace, if this does not produce any results, call PushScope (), redefine the first namespace definition, select, etc.

 var doc = new XmlDocument(); doc.LoadXml(@"<?xml version=""1.0""?> <root xmlns:my=""http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-11-30T17:39:37"" value=""1""> <my:item>test</my:item> </root>"); var nameTable = new NameTable(); var namespaceManager = new XmlNamespaceManager(nameTable); namespaceManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); namespaceManager.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml"); namespaceManager.AddNamespace("dfs", "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"); namespaceManager.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-07-14T13:45:59"); namespaceManager.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003"); // n will be null since the namespace url doesn't match var n = doc.SelectSingleNode("descendant::my:item", namespaceManager); namespaceManager.PushScope(); namespaceManager.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-11-30T17:39:37"); // will work n = doc.SelectSingleNode("descendant::my:item", namespaceManager); namespaceManager.PopScope(); 

Another option is to parse the attributes in the header and look for any contained namespaces

 foreach(XmlAttribute attribute in doc.DocumentElement.Attributes) { var url = namespaceManager.LookupNamespace(attribute.LocalName); if(url != null && url != attribute.Value) { namespaceManager.RemoveNamespace(attribute.LocalName, url); namespaceManager.AddNamespace(attribute.LocalName, attribute.Value); } } 
+1
source

You do not have to do anything. Just use "my2" or something for a second namespace. Then you need a new namespace prefix for any nodes that use the new namespace, and use the old "my" namespace prefix for all nodes that still use the old namespace.

0
source

Source: https://habr.com/ru/post/1335109/


All Articles