r - 将数据与 R xml2 中的单个 XML 节点集隔离

标签 r xml xml2

我正在尝试迭代地隔离和操作 XML 文档中的节点集,但我在 R 的 xml2 包中的 xml_find_all() 函数中遇到了奇怪的行为。有人可以帮助我理解应用于节点集?

这是一个例子:

library( xml2 )
library( dplyr )

doc <- read_xml( "<MEMBERS>
                     <CUSTOMER>
                        <ID>178</ID>
                        <FIRST.NAME>Alvaro</FIRST.NAME>
                        <LAST.NAME>Juarez</LAST.NAME>
                        <ADDRESS>123 Park Ave</ADDRESS>
                        <ZIP>57701</ZIP>
                     </CUSTOMER>
                     <CUSTOMER>
                        <ID>934</ID>
                        <FIRST.NAME>Janette</FIRST.NAME>
                        <LAST.NAME>Johnson</LAST.NAME>
                        <ADDRESS>456 Candy Ln</ADDRESS>
                        <ZIP>57701</ZIP>
                     </CUSTOMER>  
                  </MEMBERS>"  )

doc %>% xml_find_all( '//*') %>% xml_path()
# [1] "/MEMBERS"                        "/MEMBERS/CUSTOMER[1]"           
# [3] "/MEMBERS/CUSTOMER[1]/ID"         "/MEMBERS/CUSTOMER[1]/FIRST.NAME"
# [5] "/MEMBERS/CUSTOMER[1]/LAST.NAME"  "/MEMBERS/CUSTOMER[1]/ADDRESS"   
# [7] "/MEMBERS/CUSTOMER[1]/ZIP"        "/MEMBERS/CUSTOMER[2]"           
# [9] "/MEMBERS/CUSTOMER[2]/ID"         "/MEMBERS/CUSTOMER[2]/FIRST.NAME"
#[11] "/MEMBERS/CUSTOMER[2]/LAST.NAME"  "/MEMBERS/CUSTOMER[2]/ADDRESS"   
#[13] "/MEMBERS/CUSTOMER[2]/ZIP"

对象 customer.01 是一个仅包含来自该客户的数据的节点集。

kids <- xml_children( doc )

customer.01 <- kids[[1]]

customer.01
# {xml_node}
# <CUSTOMER>
# [1] <ID>178</ID>
# [2] <FIRST.NAME>Alvaro</FIRST.NAME>
# [3] <LAST.NAME>Juarez</LAST.NAME>
# [4] <ADDRESS>123 Park Ave</ADDRESS>
# [5] <ZIP>57701</ZIP>

为什么应用于 customer.01 节点集的函数也会返回 customer.02 的 ID?

xml_find_all( customer.01, "//MEMBERS/CUSTOMER/ID" )
# {xml_nodeset (2)}
# [1] <ID>178</ID>
# [2] <ID>934</ID>

如何仅返回该节点集中的值?

~~~

好的,下面的解决方案中有一个小问题,同样与 xml_find_all() 函数的范围有关。它说它可以应用于文档、节点或节点集。然而...

这种情况在应用于节点集时有效:

library( xml2 )
url <- "https://s3.amazonaws.com/irs-form-990/201501279349300635_public.xml"
doc <- read_xml( url )
xml_ns_strip( doc )
nd <- xml_find_all( doc, "//LiquidationOfAssetsDetail|//LiquidationDetail" )

nodei <- nd[[1]]
nodei
# {xml_node}
# <LiquidationOfAssetsDetail>
# [1] <AssetsDistriOrExpnssPaidDesc>LAND</AssetsDistriOrExpnssPaidDesc>
# [2] <DistributionDt>2014-11-04</DistributionDt>
# [3] <MethodOfFMVDeterminationTxt>SEE ATTACH</MethodOfFMVDeterminationTxt>
# [4] <EIN>abcdefghi</EIN>
# [5] <BusinessName>\n  <BusinessNameLine1Txt>GREENSBURG PUBLIC LIBRARY</BusinessNameLine1Txt>\n</BusinessName>
# [6] <USAddress>\n  <AddressLine1Txt>1110 E MAIN ST</AddressLine1Txt>\n  <CityNm>GREENSBURG</CityNm>\n  <StateAbbreviationCd>IN</StateAb ...
# [7] <IRCSectionTxt>501(C)(3)</IRCSectionTxt>

xml_text( xml_find_all( nodei, "AssetsDistriOrExpnssPaidDesc" ) )
# [1] "LAND"

但不是这个:

nodei <- xml_children( nd[[i]] )
nodei
# {xml_nodeset (7)}
# [1] <AssetsDistriOrExpnssPaidDesc>LAND</AssetsDistriOrExpnssPaidDesc>
# [2] <DistributionDt>2014-11-04</DistributionDt>
# [3] <MethodOfFMVDeterminationTxt>SEE ATTACH</MethodOfFMVDeterminationTxt>
# [4] <EIN>abcdefghi</EIN>
# [5] <BusinessName>\n  <BusinessNameLine1Txt>GREENSBURG PUBLIC LIBRARY</BusinessNameLine1Txt>\n</BusinessName>
# [6] <USAddress>\n  <AddressLine1Txt>1110 E MAIN ST</AddressLine1Txt>\n  <CityNm>GREENSBURG</CityNm>\n  <StateAbbreviationCd>IN</StateAb ...
# [7] <IRCSectionTxt>501(C)(3)</IRCSectionTxt>

xml_text( xml_find_all( nodei, "AssetsDistriOrExpnssPaidDesc" ) )
# character(0)

我猜这是将 xml_find_all() 应用于节点集的所有元素时出现的问题,而不是范围问题?

最佳答案

目前,您正在使用从根开始的绝对路径搜索,并使用 XPath 的双正斜杠 //,这意味着查找文档中与此路径匹配的所有项,其中包括两个客户的 ID。

对于特定节点下的特定子节点,只需使用所选节点下的相对路径:

xml_find_all(customer.01, "ID")
# {xml_nodeset (1)}
# [1] <ID>178</ID>

xml_find_all(customer.01, "FIRST.NAME|LAST.NAME")
# {xml_nodeset (2)}
# [1] <FIRST.NAME>Alvaro</FIRST.NAME>
# [2] <LAST.NAME>Juarez</LAST.NAME>

xml_find_all(customer.01, "*")
# {xml_nodeset (5)}
# [1] <ID>178</ID>
# [2] <FIRST.NAME>Alvaro</FIRST.NAME>
# [3] <LAST.NAME>Juarez</LAST.NAME>
# [4] <ADDRESS>123 Park Ave</ADDRESS>
# [5] <ZIP>57701</ZIP>

关于r - 将数据与 R xml2 中的单个 XML 节点集隔离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45866491/

相关文章:

r - 直接从包源的 URL 安装 R 包

r - 将函数列表应用于值向量

r - 如何使用geom_point()更改点的线宽?

xml - 使用 bash 脚本从 XML 文件中提取特定关键字

r - 在 Fedora 27 中的 R 中安装 xml2

r - 如何计算R中单独dfs的位置之间的距离

c# - 需要比 XML 更简单的数据源

android - 在 xml 中将 View 包装在一个框中

xml - R 中的错​​误 : no applicable method for 'xpathApply'

r - 使用带有 xml2 的管道运算符编写 XML