Openrefine: select XML 基于子节点值

Openrefine: select XML based on child node value

我在 openrefine 中有一些列包含我从 Web 服务获得的这种值。

<?xml version="1.0" encoding="UTF-8"?>
    <results>
        <result>
            <nnt>2010BOR30012</nnt>
            <ppn>146708164</ppn>
            <typerecord>m</typerecord>
        </result>
        <result>
            <nnt>2010BOR30012</nnt>
            <ppn>159823226</ppn>
            <typerecord>v</typerecord>
        </result>
</results>

我希望能够从此 XML 获得包含在 <result> 标记中的 <ppn> 值,例如,其中 <typerecord> 是 v。我尝试了基于 parseHtml 和 select 的不同方法,但目前我还没有找到解决方案来实现它。

更新@Tomalak 的评论:我一直在尝试的主要是:

与此同时,我找到了解决问题的方法,即使我更喜欢使用 grel 的解决方案,这个使用 jython 的解决方案仍然有效,所以我将它添加到那里,但这个问题仍然开放给 Grel 回答!

所以似乎可以完成这项工作的 jython 脚本是:

from xml.etree import ElementTree as ET
element = ET.fromstring(value)

resultsList = element.findall("./result")

for result in resultsList:
    typerecord = result.find("typerecord")
    if typerecord.text == "m":
        return result.find("ppn").text

我很确定有更简单的解决方案,但我仍然找不到它!

获取ppn节点,然后按"back to parent / typerecord / value=v"过滤:

//result/ppn[../typerecord/text()='v']

GREL中大概有很多解法,例如:

forEachIndex(value.parseHtml().select("typerecord"), i, v, if(v.htmlText()=="v",value.parseHtml().select("ppn")[i].htmlText(),null)).join(' ')

with(value.parseHtml().select('result'), e, filter(e.join('|').split('|'), v, v.contains('v')))[0].parseHtml().select("ppn")[0].htmlText()

forEach(value.parseHtml().select("result"),e,if(e.select("typerecord")[0].htmlText()=="v", e.select("ppn")[0].ownText(), null)).join('')

但是我不喜欢这种俄罗斯套娃。您自己在 Jython 中使用 xml.etree 的解决方案更加清晰。怎么了?

我同意 Ettore 的观点 - 在这种情况下,Jython 将提供最简单的解决方案。但是如果你想用 GREL 来做,我的解决方案是:

使用 GREL 和 parseHtml 尽管有它的名字,但您可以使用 parseHtml 函数解析 XML。 select 函数接受 jsoup select 或

value.parseHtml().select("result")

会得到所有的结果元素

要select 只有包含 typerecord=v 的结果元素,您必须将其与过滤函数结合使用: filter(value.parseHtml().select("result"),e,e.select("typerecord")[0].ownText()=="v")

这将为您提供一个结果元素数组,其中 typerecord=v

所以最后你可以通过这些迭代到 select ppn 值:

forEach(filter(value.parseHtml().select("result"),e,e.select("typerecord")[0].ownText()=="v"), f, f.select("ppn")[0].ownText())