我可以从我要阅读的xml文件中创建一个XmlNamespaceManager对象吗?

时间:2011-01-11 15:15:48

标签: c# xml sharepoint infopath

我在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对象,因为这些都包含在标题中? 我无法找到一个简单的方法。

3 个答案:

答案 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”命名空间前缀。