按xpath从r中的文件中删除或过滤XML节点



我有非常非常大的复杂xml文件(如下https://github.com/HL7/C-CDA-Examples/blob/master/General/Parent%20Document%20Replace%20Relationship/CCD%20Parent%20Document%20Replace%20(C-CDAR2.1).xml所示)要处理,但只需要特定xpath(节点)上的属性和值。通过去除不需要的节点,可以缩短处理时间,在详细处理之前过滤掉绒毛。

到目前为止,我已经尝试使用:xml_remove

xmlfile <- paste0(dir,"xmlFiles/",filelist[k])
file<-read_xml(xmlfile)
file<-xml_ns_strip(file)
for(counx in 1:nrow(xpathTable)){   
xr <- xml_find_all(file, xpath =paste0('/',toString(xpathTable$xpaths[counx])) )
xml_remove(xr, free = TRUE)
file<-file              
}

这对于删除少量节点很有效,但随着数量的增加而崩溃(>100)

下面是我想要得到的一个例子

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
<ISBN>
<Random>12354</Random>
</ISBN>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<ISBN>
<Random>12345</Random>
</ISBN>
<price>39.95</price>
</book>
</bookstore>

通过xpath筛选

  • /书店/书/标题
  • <
  • /书店/书/年/gh>
  • /书店/书/ISBN/随机
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="cooking">
<title lang="en">Everyday Italian</title>       
<year>2005</year>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<year>2005</year>
<ISBN>
<Random>12354</Random>
</ISBN>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<year>2003</year>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<year>2003</year>
<ISBN>
<Random>12345</Random>
</ISBN>
</book>
</bookstore> 

看起来像XQuery作业,例如,您可以像这样重新创建文档

<bookstore>{
for $book in /bookstore/*
return <book category="{$book/@category}">
{$book/title}
{$book/year}
{$book/ISBN}
</book>
}</bookstore>

使用书的例子得到它下面的结果。您可以在这里使用XQuery作为选项进行在线测试https://www.videlibri.de/cgi-bin/xidelcgi

可能有一些方法可以从R中运行XQuery,但我宁愿使用像xidel这样的工具在命令行中执行预处理步骤。

所有元素都可以在一个适用于多种语言的XPath 1.0表达式中查找:

/bookstore/book/descendant::*[name()="title" or name()="year" or name()="Random"]

当量/类似的表达式:

/bookstore/book/title | /bookstore/book/year | /bookstore/book/ISBN/Random
//book/@category | //book/year | //ISBN/Random

过滤掉元素:

//book/*[not(name()="title" or name()="year" or name()="ISBN" or name()="Random")]

对于有名称空间的xml,如果不使用名称空间处理,可以使用local-name()代替name()

对于给定的示例和元素,在命令行上进行测试:

echo 'cat /bookstore/book/descendant::*[name()="title" or name()="year" or name()="Random"]' | xmllint --shell test.xml

结果:

/ > cat /bookstore/book/descendant::*[name()="title" or name()="year" or name()="Random"]
-------
<title lang="en">Everyday Italian</title>
-------
<year>2005</year>
-------
<title lang="en">Harry Potter</title>
-------
<year>2005</year>
-------
<Random>12354</Random>
-------
<title lang="en">XQuery Kick Start</title>
-------
<year>2003</year>
-------
<title lang="en">Learning XML</title>
-------
<year>2003</year>
-------
<Random>12345</Random>
/ >

关于提到的R崩溃,值得在这里查看。

最新更新