如何使用带有 XPath 的 Java 中的命名空间查询 XML? [英] How to query XML using namespaces in Java with XPath?

查看:25
本文介绍了如何使用带有 XPath 的 Java 中的命名空间查询 XML?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我的 XML 看起来像这样(没有 xmlns)时,我可以使用 XPath 轻松查询它,例如 /workbook/sheets/sheet[1]

When my XML looks like this (no xmlns) then I can easly query it with XPath like /workbook/sheets/sheet[1]

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook>
  <sheets>
    <sheet name="Sheet1" sheetId="1" r:id="rId1"/>
  </sheets>
</workbook>

但是当它看起来像这样我就不能

But when it looks like this then I can't

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  <sheets>
    <sheet name="Sheet1" sheetId="1" r:id="rId1"/>
  </sheets>
</workbook>

有什么想法吗?

推荐答案

在第二个示例 XML 文件中,元素绑定到一个命名空间.您的 XPath 正在尝试处理绑定到默认无命名空间"命名空间的元素,因此它们不匹配.

In the second example XML file the elements are bound to a namespace. Your XPath is attempting to address elements that are bound to the default "no namespace" namespace, so they don't match.

首选方法是使用命名空间前缀注册命名空间.它使您的 XPath 更易于开发、阅读和维护.

The preferred method is to register the namespace with a namespace-prefix. It makes your XPath much easier to develop, read, and maintain.

但是,注册命名空间并在 XPath 中使用命名空间前缀并不是强制性的.

可以制定一个 XPath 表达式,该表达式使用元素的通用匹配和限制所需 local-name()local-name() 的匹配的谓词过滤器代码>命名空间-uri().例如:

You can formulate an XPath expression that uses a generic match for an element and a predicate filter that restricts the match for the desired local-name() and the namespace-uri(). For example:

/*[local-name()='workbook'
    and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main']
  /*[local-name()='sheets'
      and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main']
  /*[local-name()='sheet'
      and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main'][1]

如您所见,它生成了非常长且冗长的 XPath 语句,非常难以阅读(和维护).

As you can see, it produces an extremely long and verbose XPath statement that is very difficult to read (and maintain).

您也可以只匹配元素的 local-name() 而忽略命名空间.例如:

You could also just match on the local-name() of the element and ignore the namespace. For example:

/*[local-name()='workbook']/*[local-name()='sheets']/*[local-name()='sheet'][1]

但是,您可能会遇到匹配错误元素的风险.如果您的 XML 包含使用相同 local-name(),您的 XPath 可能会匹配错误的元素并选择错误的内容:

However, you run the risk of matching the wrong elements. If your XML has mixed vocabularies (which may not be an issue for this instance) that use the same local-name(), your XPath could match on the wrong elements and select the wrong content:

这篇关于如何使用带有 XPath 的 Java 中的命名空间查询 XML?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆