首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R xml2中从单个xml2中分离数据

R xml2中从单个xml2中分离数据
EN

Stack Overflow用户
提问于 2017-08-24 16:12:46
回答 1查看 3.2K关注 0票数 2

我试图迭代地从XML文档中分离和操作节点集,但是我在R中的xml_find_all()函数中得到了一个奇怪的行为,有人能帮助我理解应用于节点集的函数的范围吗?

下面是一个示例:

代码语言:javascript
复制
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是一个节点集,仅包含来自该客户的数据。

代码语言:javascript
复制
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?

代码语言:javascript
复制
xml_find_all( customer.01, "//MEMBERS/CUSTOMER/ID" )
# {xml_nodeset (2)}
# [1] <ID>178</ID>
# [2] <ID>934</ID>

如何只返回节点集中的值?

代码语言:javascript
复制

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

这种情况适用于节点集:

代码语言:javascript
复制
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"

但不是这个:

代码语言:javascript
复制
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()应用于节点集的所有元素而不是范围问题的问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-24 18:38:34

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

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

代码语言:javascript
复制
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>
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45866491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档