我有以下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 网站上得到了各种结果,并在这里总结了结果。
你感到困惑是对的。
仅删除ss:Data
不应导致//Names
在声明默认命名空间urn:schemas-microsoft-com:office:spreadsheet
时突然选择Workbook
的Names
子项Workbook
。 您似乎偶然发现了 xpather.com 中的错误。请注意,它们的打开默认 XML 具有以下有关命名空间的免责声明:
此应用程序处于早期测试版,因此请 原谅。支持 XPath 2.0,但命名空间仍然存在 添加,它们可能尚未完全工作。请发送您的意见 至: xpather.com@gmail.com
另请参阅(有关命名空间中的常规 XPath 指南(:
- XPath 如何处理 XML 命名空间?
- 在 C# 中使用具有默认命名空间的 xpath
另一个 xpather.com 问题
目前,xpather.com 不明白元素名称可能包含句点(.
(字符。
还有另一个 xpather.com 问题
这个完全兼容的 XPath,
//item/comment()[not(preceding-sibling::*)]
在 xpather.com 上导致以下(不正确(错误消息:
类型错误:无法读取未定义的属性"子位置">
我决定将其添加为答案而不是对原始问题的编辑,因为我仍然可能缺少一些东西,但是由于@GSerg和@kjhughes的评论/答案,我做了一些调查。如果事实证明这很有用,我可以编辑问题并将其添加。
以下是用于在线 XPath 评估的少数网站,以及它们在我的方案中的行为方式。
+--------------------------------------------------------+--------------+-------------+------------+------------+
| | With <ss:Data> | Without <ss:Data> |
+--------------------------------------------------------+--------------+-------------+------------+------------+
| | //Names | //ss:Names | //Names | //ss:Names |
+--------------------------------------------------------+--------------+-------------+------------+------------+
| https://www.freeformatter.com/xpath-tester.html | No Match | Match | Match | Match |
| https://codebeautify.org/Xpath-Tester | No Match | No Match | No Match | No Match |
| http://xpather.com/ | No Match | Match | Match | Match |
| https://www.webtoolkitonline.com/xml-xpath-tester.html | No Match | Error | No Match | Error |
| http://www.utilities-online.info/xpath/#.Xe4VtTP7QuU | No Match | No Match | No Match | No Match |
| https://extendsclass.com/xpath-tester.html | No Match | Match | No Match | Match |
+--------------------------------------------------------+--------------+-------------+------------+------------+
根据我对到目前为止的答案的理解,唯一表现得完全合理的似乎是 ExtendsClass,尽管 freeformatter 和 xpather 在指定命名空间时确实会产生正确的结果。
还应该指出的是,xpather确实明确宣布了其测试状态,并且还具有漂亮的UI。