F.P*_*F.P 5 .net c# xml xpath xml-namespaces
当我想使用XPath遍历我的XmlDocument时,我遇到了文档中有许多丑陋的命名空间的问题,所以我开始使用NamespaceManagerXPath.
XML看起来像这样
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="KA0100401">
<Table>
<Row>
<Cell>Data</Cell>
</Row>
<!-- more rows... -->
</Table>
</Worksheet>
<Worksheet ss:Name="KA0100402">
<!-- .... --->
</Worksheet>
</Workbook>
Run Code Online (Sandbox Code Playgroud)
现在,从我在本文档中看到的"urn:schemas-microsoft-com:office:spreadsheet"是默认命名空间,因为它位于根元素上.
所以天真地,我配置了NamespaceManager这样的:
XmlDocument document = new XmlDocument();
document.Load(reader);
XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
manager.AddNamespace(String.Empty, "urn:schemas-microsoft-com:office:spreadsheet");
manager.AddNamespace("o", "urn:schemas-microsoft-com:office:office");
manager.AddNamespace("x", "urn:schemas-microsoft-com:office:excel");
manager.AddNamespace("ss", "urn:schemas-microsoft-com:office:spreadsheet");
manager.AddNamespace("html", "http://www.w3.org/TR/REC-html40");
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试访问节点时
foreach (XmlNode row in document.SelectNodes("/Workbook/Worksheet[1]/Table/Row", manager))
Run Code Online (Sandbox Code Playgroud)
我从来没有得到任何结果.我的印象是,通过使用空前缀设置第一个命名空间,在搜索该工作空间中的节点时,我不需要设置它.
但是,因为它是在规定AddNamespace的方法:
如果XPath表达式不包含前缀,则假定名称空间统一资源标识符(URI)是空名称空间.
这是为什么?而且,更重要的是:如何访问默认命名空间中的节点,如果不使用前缀将它们设置为空命名空间?
如果我在搜索节点时甚至无法访问它,那么在管理器上设置默认命名空间有什么用呢?
使用表达式上下文中的名称空间声明,将节点测试中的QName扩展为扩展名.这与开始和结束标记中的元素类型名称进行扩展的方式相同,只是不使用使用xmlns声明的默认名称空间:如果QName没有前缀,则名称空间URI为null(这是相同的方式属性名称已扩展).如果QName具有在表达式上下文中没有名称空间声明的前缀,则会出错.
所以这不是一个问题,NamespaceManager而是定义XPath的工作方式.
您缺少的一点是您在其中使用的前缀NamespaceManager不必与XML文档中的前缀类似.您可以使用xcel前缀urn:schemas-microsoft-com:office:excel,如果你想和sp前缀urn:schemas-microsoft-com:office:spreadsheet.实际上,您已经在命名空间管理器中为该URN分配了一个前缀,因此您可以使用它:
foreach (XmlNode row in
document.SelectNodes("/ss:Workbook/ss:Worksheet[1]/ss:Table/ss:Row", manager))
Run Code Online (Sandbox Code Playgroud)
关于这个问题:
如果我在搜索节点时甚至无法访问它,那么在管理器上设置默认命名空间有什么用呢?
好处是它不仅XmlNamespaceManager用于评估XPath.例如,它可用于跟踪XML文档中的名称空间,其中存在默认名称空间的概念.
@JLRishe 的答案对于访问默认命名空间中的节点是正确的(即始终将前缀映射到 中的默认命名空间XmlNamespaceManager)。
从您的引用( MSDN XmlNamespaceManager.AddNamespace )中读取链接的整个上下文,发现 XPath 表达式中不使用默认的“空”前缀。
前缀 类型:System.String
与要添加的命名空间关联的前缀。使用 String.Empty 添加默认命名空间。>
注意如果 XmlNamespaceManager 将用于解析 XML 路径语言 (XPath) 表达式中的命名空间,则必须指定前缀。如果 XPath 表达式不包含前缀,则假定命名空间统一资源标识符 (URI) 是空命名空间。有关 XPath 表达式和 XmlNamespaceManager 的详细信息,请参阅 XmlNode.SelectNodes 和 XPathExpression.SetContext 方法。
| 归档时间: |
|
| 查看次数: |
997 次 |
| 最近记录: |