groovy - 在 Groovy 中使用 XML 命名空间和 XmlSlurper - 如何正确查询路径?
问题描述
我有以下示例 xml:
<root>
<table xmlns:h="http://www.w3.org/TR/html4/">
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>
<table xmlns:f="https://www.w3schools.com/furniture">
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>
</root>
def slurper = new XmlSlurper().parseText(someXMLText)
def hNs = new groovy.xml.Namespace(
"http://www.w3.org/TR/html4/", 'h')
def fNs = new groovy.xml.Namespace(
"https://www.w3schools.com/furniture", 'h')
println slurper.root[hNs.table].tr.td //not giving any response
因为有两个具有不同标签的表格标签。如何Apples
使用命名空间的 gpath 获取标签下的值。
解决方案
您对 XML 文档的使用不正确。当您定义一个类似 的命名空间时xmlns:h="http://www.w3.org/TR/html4/"
,您会创建一个必须显式使用的前缀。否则,如果文档未分配给任何节点,则无法使用此前缀查询文档。您需要将其分配给至少一个table
标签才能使用它。
<h:table xmlns:h="http://www.w3.org/TR/html4/">
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</h:table>
但是,如果要为每个table
节点(及其子节点)创建默认命名空间,则需要跳过前缀并定义一个没有它的命名空间。
<table xmlns="http://www.w3.org/TR/html4/">
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>
发现细微的差别——在第二个例子中,我们用xmlns
属性定义了命名空间,而不是xmlns:h
前一个例子中的那个。
使用默认命名空间时,可以使用该declareNamespace
方法为默认命名空间定义前缀。这允许您使用像h:table
这样的选择器来引用声明的命名空间映射中的前缀table
定义的命名空间中的标记。h
考虑以下示例:
def source = '''<root>
<table xmlns="http://www.w3.org/TR/html4/">
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>
<table xmlns="https://www.w3schools.com/furniture">
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>
</root>'''
def root = new XmlSlurper().parseText(source).declareNamespace([
h: "http://www.w3.org/TR/html4/",
f: "https://www.w3schools.com/furniture"
])
assert root."h:table".tr.td.first().text() == "Apples"
assert root."h:table".tr.td.last().text() == "Bananas"
assert root."f:table".width.toInteger() == 80
table
在此示例中,我们使用一个 XML 文档,该文档为标签定义了两个不同的默认命名空间。使用该declareNamespace
方法,我们可以为这些命名空间定义前缀,以便我们可以在标签选择器中使用前缀。
如果出于某种原因,您需要在table
节点级别使用前缀定义命名空间,则至少需要在顶层使用此前缀。
def source = '''<root>
<h:table xmlns:h="http://www.w3.org/TR/html4/">
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</h:table>
<f:table xmlns:f="https://www.w3schools.com/furniture">
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</f:table>
</root>'''
def root = new XmlSlurper().parseText(source).declareNamespace([
h: "http://www.w3.org/TR/html4/",
f: "https://www.w3schools.com/furniture"
])
assert root."h:table".tr.td.first().text() == "Apples"
assert root."h:table".tr.td.last().text() == "Bananas"
assert root."f:table".width.toInteger() == 80
希望能帮助到你。
推荐阅读
- azure - 在 Azure Logic App 的结果视图中获取“无法获取”
- c - 如何在 C 编程中将数据保存在 .txt 文件中
- django - Django manage.py 文件的声纳云安全热点
- python - 从python中的文本中删除空字符串
- c - 这个内存泄漏在哪里?
- acumatica - 如何在 Acumatica 报告变量中连接刺痛
- c# - 任务“ResolvePackageAssets”的意外错误
- php - 项目返工:我应该使用主复合键和 json 来使用 Laravel 进行翻译吗?
- function - 创建地图
带有字符串的第一个和最后一个字符 - powerbi - 添加自定义小计