2011-09-28 75 views
0

我有几个XML文档,它们都具有相同的结构(元素名称,属性名称和层次结构)。如何在XmlDocument中处理XML中的命名空间c#

但是,某些元素和属性在每个XML文档中都有自定义名称空间,这些名称空间在设计时不为人所知。他们改变,不要问...

如何使用一组XPath遍历文档时如何处理?

我应该在处理之前删除所有的命名空间吗?

我可以使用XmlNamespaceManager自动注册所有名称空间吗?

有什么想法?

更新:一些例子(为了清楚省略了命名空间声明):

<root> 
    <child attr="val" /> 
</root> 

<root> 
    <x:child attr="val" /> 
</root> 

<root> 
    <y:child z:attr="val" /> 
</root> 

感谢

+0

命名空间或前缀?如果前缀 - 无需执行任何操作,如果名称空间 - 使用XmlNamespaceManager注册将不会有任何好处,因为您不能提前创建XPath而不知道名称空间。有关使用本地名称的解答可能是最好的方法。 –

回答

1

我相信你会发现在这个线程#1

XPath + Namespace Driving me crazy

一些很好的启示

在我看来你有两种解决方案之一:

1-如果所有可能的命名空间是前手知道,那么你就可以在你的XmlNamespaceManager解析开始

2-使用XPath命名空间无关的选择

当然之前注册所有这些你总是可以从任何内联命名空间中清理xml文档,并在没有命名空间的情况下开始在一个干净的uniorm xml上进行解析..但老实说,我不认为增加这个开销步骤会带来收益。

2

假设你有以下的XML:

<root xmlns="first"> 
    <el1 xmlns="second"> 
    <el2 xmlns="third">... 

你可以写你的查询忽略以下方式命名空间: /*[local-name()='root']/*[local-name()='el1']/*[local-name()='el2'] 等 当然你也可以遍历整个文档以获得命名空间和负载他们到nsmanager。但是通常情况下,这会导致您评估文档中的每个节点。在这种情况下,将文档视为对象树并且不使用XPath会更快。

+0

这看起来像答案,特别是因为命名空间前缀是不同的 –

0

Scott Hanselman有关于提取XML文档中所有XML命名空间的nice article。据推测,当你得到所有的XML命名空间时,你可以遍历所有的命名空间管理器。

0

你可以尝试这样的事情剥离的命名空间:

//Implemented based on interface, not part of algorithm 
public string RemoveAllNamespaces(string xmlDocument) 
{ 
    return RemoveAllNamespaces(XElement.Parse(xmlDocument)).ToString();  
} 

//Core recursion function 
private XElement RemoveAllNamespaces(XElement xmlDocument) 
{ 
    if (!xmlDocument.HasElements) 
    { 
     XElement xElement = new XElement(xmlDocument.Name.LocalName); 
     xElement.Value = xmlDocument.Value; 
     return xElement; 
    } 
    return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el))); 
} 

见彼得Stegnar的回答此处了解详情:
How to remove all namespaces from XML with C#?

0

您还可以使用直接节点测试使用通配符,这将匹配任何名称空间(或缺少名称空间):

$your-document/*:root/*:child/@*:attr