【发布时间】:2020-03-31 09:43:36
【问题描述】:
我有以下 XML:
<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<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">
<Names>
<NamedRange ss:Name="SomeNamedRange" ss:RefersTo="=Control!R1C1:R51C4"/>
</Names>
<Worksheet ss:Name="Control" ss:Protected="1">
<Table ss:ExpandedColumnCount="4" ss:ExpandedRowCount="51">
<Row>
<Cell ss:StyleID="s145">
<Comment ss:Author="Some comment here">
<ss:Data xmlns="http://www.w3.org/TR/REC-html40"></ss:Data>
</Comment>
</Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
我想用 XPath 获取 Names 元素,所以我尝试:
//Names
但这不起作用。到目前为止,我已经找到了许多解决此问题的方法。
//ss:Names
//*:Names
//*[local-name()='Names']
或者,我可以删除以下元素:
<ss:Data xmlns="http://www.w3.org/TR/REC-html40"></ss:Data>
很明显,这与命名空间有关,但我仍然不明白发生了什么。所以我有两个问题:
- 为什么删除
ss:Data元素会影响读取Names元素? - 鉴于在顶部声明了 5 个命名空间,为什么
Names元素被认为在ss命名空间中(当ss:Data元素存在时)? - 这里正确的一般方法是什么?我觉得我缺少一些关于 XML 或 XPath 的一般信息
编辑:
此问题不仅限于http://xpather.com/。我在不同的 XPath 网站上得到了各种结果,并总结了结果here。
【问题讨论】:
-
您的
ss前缀指的是与xmlns、urn:schemas-microsoft-com:office:spreadsheet定义的默认命名空间相同的命名空间。正是该值定义了元素所属的命名空间,而不是前缀。所以所有ss-前缀元素和所有非前缀元素都属于同一个命名空间urn:schemas-microsoft-com:office:spreadsheet。<ss:Data xmlns="http://www.w3.org/TR/REC-html40">更改了其子级的默认命名空间,因此内部的无前缀Names将不符合urn:schemas-microsoft-com:office:spreadsheet的条件。 -
啊,好吧,我想我明白了第一点。至于第二部分,
<Names>元素不是<ss.Data>元素的子元素,为什么会受到它的影响? -
重复链接将向未来的读者解释如何将 XPath 与命名空间一起使用。抱歉,但考虑到您对问题的命名方式,它们的数量会比您的数量多。您的特定问题要窄得多:您在 xpather.com 中偶然发现了一个错误。请注意,它们的默认 XML 有以下关于命名空间的免责声明:支持 XPath 2.0,但 命名空间仍在添加中,它们可能还没有完全工作。你是对的感到困惑: 只是删除
ss:Data不应该导致//Names突然选择一些东西。 -
...完成。不客气。与 XPather.com 一样的任何其他在线 XPath 站点也将不兼容。如果您发现任何问题,请告诉我们。我已通过电子邮件将此 Q/A 的链接发送至
xpather.com@gmail.com。
标签: c# xml xpath xml-namespaces