在 XPather.com 上使用 XML 命名空间的奇怪 XPath 行为?

Strange XPath behavior using XML namespaces on XPather.com?

我有以下 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>

很明显,这与名称空间有关,但我仍然不太明白发生了什么。所以我有两个问题:

  1. 为什么删除 ss:Data 元素会影响能够读取 Names 元素?
  2. 鉴于在顶部声明了 5 个命名空间,为什么 Names 元素被认为在 ss 命名空间中(当 ss:Data 元素存在时)?
  3. 这里正确的一般方法是什么?我觉得我缺少一些关于 XML 或 XPath
  4. 的一般信息

编辑:

此问题不限于 http://xpather.com/. I have had various results with different XPath websites, and have summarised the results

你的疑惑是对的。

Workbook 声明默认名称空间时,仅删除 ss:Data 不应导致 //Names 突然 select WorkbookNames 子级urn:schemas-microsoft-com:office:spreadsheet 个。您似乎偶然发现了 xpather.com 中的错误。请注意,他们的开放,默认 XML 有以下关于命名空间的免责声明:

This application is in an early beta version so please be forgiving. XPath 2.0 is supported but namespaces are still being added and they may not fully work yet. Please send your comments to: xpather.com@gmail.com

另请参阅(有关命名空间指南中的一般 XPath):

  • Using Xpath With Default Namespace in C#

另一个 xpather.com 问题

目前,xpather.com 不理解元素名称可能包含句点 (.) 字符。


还有一个 xpather.com 问题

这个完全兼容的 XPath,

//item/comment()[not(preceding-sibling::*)]

导致 xpather.com 上出现以下(不正确的)错误消息:

TypeError: Cannot read property 'childPosition' of undefined

我决定添加这个作为答案而不是对原始问题的编辑,因为我仍然可能遗漏了一些东西,但感谢@GSerg 和@kjhughes 的 comment/answers,我做了一些调查。如果这证明有用,我可以编辑问题并将其添加。

以下只是一些用于在线 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, although freeformatter and xpather 在指定命名空间时确实产生了正确的结果。

还需要指出的是,xpather确实明确宣布了它的测试状态,并且也有一个很好的UI。