C# 如何在XMLC文档中处理XML中的名称空间#
我有几个XML文档,它们都具有相同的结构(元素名、属性名和层次结构) 但是,有些元素和属性在每个XML文档中都有自定义名称空间,而这些名称空间在设计时是未知的。他们变了,不要问 当使用一组XPath遍历文档时,如何处理这个问题 我应该在处理之前删除所有名称空间吗 我可以自动向XmlNamespaceManager注册所有名称空间吗 有什么想法吗 更新:一些示例(为了清晰起见省略了名称空间声明):C# 如何在XMLC文档中处理XML中的名称空间#,c#,xml,C#,Xml,我有几个XML文档,它们都具有相同的结构(元素名、属性名和层次结构) 但是,有些元素和属性在每个XML文档中都有自定义名称空间,而这些名称空间在设计时是未知的。他们变了,不要问 当使用一组XPath遍历文档时,如何处理这个问题 我应该在处理之前删除所有名称空间吗 我可以自动向XmlNamespaceManager注册所有名称空间吗 有什么想法吗 更新:一些示例(为了清晰起见省略了名称空间声明): 谢谢我相信您会在这个Stackoverflow线程中找到一些很好的见解 我认为您有两种解决方案
谢谢我相信您会在这个Stackoverflow线程中找到一些很好的见解 我认为您有两种解决方案: 1-如果所有可能的名称空间集都是事先知道的,那么在开始解析之前,您可以将它们全部注册到XmlNamespaceManager中 2-使用Xpath命名空间不可知选择器
当然,您始终可以从任何内联名称空间中删除xml文档,并在没有名称空间的干净的非格式xml上开始解析。。但老实说,我看不出增加这一开销步骤有什么好处。我相信您会在这个Stackoverflow线程中找到一些很好的见解 我认为您有两种解决方案: 1-如果所有可能的名称空间集都是事先知道的,那么在开始解析之前,您可以将它们全部注册到XmlNamespaceManager中 2-使用Xpath命名空间不可知选择器
当然,您始终可以从任何内联名称空间中删除xml文档,并在没有名称空间的干净的非格式xml上开始解析。。但老实说,我看不出增加这一开销步骤有什么好处。假设您有以下xml:
<root xmlns="first">
<el1 xmlns="second">
<el2 xmlns="third">...
...
您可以通过以下方式编写忽略名称空间的查询:
/*[local-name()='root']/*[local-name()='el1']/*[local-name()='el2']
等
当然,您可以迭代整个文档以获得名称空间并将其加载到nsmanager中。但在一般情况下,这将导致您计算文档中的每个节点。在这种情况下,只将文档视为对象树而不使用XPath会更快
<root xmlns="first">
<el1 xmlns="second">
<el2 xmlns="third">...
...
您可以通过以下方式编写忽略名称空间的查询:
/*[local-name()='root']/*[local-name()='el1']/*[local-name()='el2']
等
当然,您可以迭代整个文档以获得名称空间并将其加载到nsmanager中。但在一般情况下,这将导致您计算文档中的每个节点。在这种情况下,只将文档视为对象树而不使用XPath会更快。Scott Hanselman有一个关于提取XML文档中所有XML名称空间的方法。大概,当您获得所有XML名称空间时,您可以对所有名称空间进行迭代并在名称空间管理器中注册它们。Scott Hanselman有一个关于提取XML文档中所有XML名称空间的方法。大概,当您获得所有XML名称空间时,您可以对所有名称空间进行迭代,并在名称空间管理器中注册它们。您可以尝试以下方法来剥离名称空间:
//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)));
}
有关更多详细信息,请参见Peter Stegnar的回答:您可以尝试以下方法来剥离名称空间:
//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)));
}
有关更多详细信息,请参见Peter Stegnar的回答:您还可以使用带有通配符的直接节点测试,它将匹配任何名称空间(或缺少名称空间):
您还可以使用带有通配符的直接节点测试,它将匹配任何名称空间(或缺少名称空间):
名称空间还是前缀?如果使用前缀(无需执行任何操作),如果使用名称空间(使用XmlNamespaceManager注册),则没有任何好处,因为您将无法在不知道名称的情况下提前创建XPath。关于使用本地名称的答案可能是最好的方法。名称空间还是前缀?如果使用前缀(无需执行任何操作),如果使用名称空间(使用XmlNamespaceManager注册),则没有任何好处,因为您将无法在不知道名称的情况下提前创建XPath。关于使用本地名称的答案可能是最好的方法。这看起来像答案,特别是在命名空间前缀不同的情况下。这看起来像答案,特别是在命名空间前缀不同的情况下