【问题标题】:Retrieving empty and non-empty node with xpath使用 xpath 检索空和非空节点
【发布时间】:2026-01-07 20:25:03
【问题描述】:

我正在尝试获得 XML 的良好表示...为了简单起见,假设我们有以下 XML

<div>
    <em>5</em>
    <em></em>
    <em></em>
    <em>A</em>
</div>

理想情况下,我想将其转换为具有一列的表格:

| em |
------
| "5"| 
| "" |
| "" |
| "A"|

(我在这里用引号清楚地表明我也想要空节点)

我尝试了几个 xpath 查询.. 最简单的一个是我用 R 测试过的,在这里我会得到

z = read_xml("<div>
        <em>5</em>
        <em></em>
        <em></em>
        <em>A</em>
</div>")
z

xml_find_all(z,"//*[name() = 'em']/text()")

{xml_nodeset (2)}
[1] 5
[2] A

大多数其他问题是关于仅检测空/非空单元格..或选择第一个非空单元格..但我不知道如何在这里使用它。

我的一个想法是尝试使用 concat... 向所有节点(包括空节点)添加一些字符串。但是,这是一个 Xpath 2.0 解决方案 (AFAIK),这不是一个可行的解决方案。

最终解决方案(从此 XML 中提取信息)将在 Hive 中实现。我使用一些 Serde 功能来获取信息..然后将其存储为数组..然后我想将其转换为普通表..但如果由于长度差异而未检索到缺失值,则这是不可能的

【问题讨论】:

  • 此解决方案//em/string() 适用吗?
  • @Andersson 太糟糕了,它不起作用.. 用 R 和 Hive 尝试过.. 我只是用 string() 替换了 text()。我希望会有一个名为 content() 的函数或类似的函数......但我还没有找到它。我现在看到的唯一解决方案就是获取整个节点......然后使用一些正则表达式来减少不必要的部分。

标签: r xpath hive xml2


【解决方案1】:

R 你可以这样做:

library(xml2)
library(magrittr)
z = read_xml("<div>
             <em>5</em>
             <em></em>
             <em></em>
             <em>A</em>
        </div>")
z %>% 
    xml_find_all('em') %>% 
    xml_text()

#> [1] "5" ""  ""  "A"

或者,没有管道:

library(xml2) 
xml_text(xml_find_all(z, 'em'))
#> [1] "5" ""  ""  "A"

【讨论】:

  • 谢谢您提供这些信息!不知道。将查看这些函数的代码,看看我是否可以在 Hive 中复制它。
【解决方案2】:

可以在 Hive 中使用 xpath() 来实现。不幸的是,Hive 实现了 xpath 1.0。因此,无法以更优雅的方式帮助处理缺失值的函数。

我可以处理它的唯一方法是在 xpath 表达式中使用“或”语句,当 xpath 值为空时,该语句将输出默认值。 在您的情况下,没有默认元素,因此我使用 regexp_replace() 创建了一个:

select xplode.*
     from (select 0) t
     lateral view explode(xpath(regexp_replace('<div><em>5</em><em></em><em></em><em>A</em></div>', '<em>','<em dflt = "">'),'div/em/text()| div/em[not(./text())]/@dflt')) xplode  as em;

【讨论】: