我在sharepoint上运行了一些c#代码,用于检查infopath文档的xml内部以查看是否应该检查文档或丢弃文档。
代码对于我创建的几个不同的表单模板工作正常,但是在我的错误表单上失败了。 我发现我正在创建的XmlNamespaceManager包含“MY”名称错误的错误定义。
我会尝试解释
我有这个代码来decalre我的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");`
然后我可以使用以下代码行来搜索我之后的xml
XPathNavigator nav = xml.CreateNavigator().SelectSingleNode("//my:HasSaved", NamespaceManager);
nav.Value然后得到我想要的数据。
这一切都适用于我的几个表单模板。我有一个新的表单模板,并发现我需要使用该行代替
NamespaceManager.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-11-30T17:39:37");
日期不同。
我的问题是我无法添加两次,因为只有一组表格可以使用。
所以我的问题是。有没有办法可以从XML文件生成NamespaceManager对象,因为这些都包含在标题中? 我无法找到一个简单的方法。
答案 0 :(得分:4)
我找到了一种方法。它可以从XmlDocument对象中提取,而不是添加“my”命名空间。这可能只是运气,它以这种方式工作,但我很满意。
NamespaceManager.AddNamespace("my", formXml.DocumentElement.NamespaceURI
formXML是从infopath XML
创建的XmlDocument答案 1 :(得分:1)
一种选择是尝试使用第一个命名空间加载xml节点,如果没有给出任何结果,请调用PushScope(),覆盖第一个命名空间定义,选择等等......
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();
另一种选择是解析标题中的属性并查找任何包含的名称空间
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);
}
}
答案 2 :(得分:0)
你不需要做这样的事情。只需使用“my2”或其他东西作为第二个命名空间。然后,您需要为使用新命名空间的任何节点使用新的命名空间前缀,并对仍使用旧命名空间的所有节点使用旧的“my”命名空间前缀。