使用 R 解析包含多个节点集的 XML

问题描述

我有一个包含很多子级和子级的 xml 文件(我可能在这里使用了错误的术语)。我在 StackOverflow 上四处寻找这种复杂事物的样本,但是我对 XML 包和 xml2 包的尝试没有提取任何字符。我正在尝试从 xml 中解析出节点“BusNm”以及地址数据,然后将这些变量加载到数据帧中。

这是文件的示例。我希望我正确加载了它。大家怎么看?

<?xml version="1.0" encoding="ISO-8859-1"?>
<IAPDFirmSECReport GenOn="2021-03-19">
<Firms>
<Firm>
<Info SECRgnCD="bro" FirmCrdNb="133693" SECNb="801-73527" BusNm="H/2 CAPITAL PARTNERS" LegalNm="H/2 CREDIT MANAGER LP" UmbrRgstn="Y"/>
<MainAddr Strt1="680 WASHINGTON BOULEVARD" Strt2="SEVENTH FLOOR" City="STAMFORD" State="CT" Cntry="United States" PostlCd="06901-3700" PhNb="203-569-4000" FaxNb="203-569-4178"/>
<MailingAddr/>
<Rgstn FirmType="Registered" St="APPROVED" Dt="2012-03-26"/>
<NoticeFiled>
<States RgltrCd="CT" St="FILED" Dt="2015-01-08"/>
<States RgltrCd="NY" St="FILED" Dt="2017-03-02"/>
</NoticeFiled>
<Filing Dt="2020-03-26" FormVrsn="10/2017"/>
<FormInfo>
<Part1A>
<Item1 Q1F5="2" Q1I="N" Q1M="N" Q1N="N" Q1O="N" Q1P="549300XR0J90YJAJ0H10">
<WebAddrs/>
</Item1>
<Item2A Q2A1="Y" Q2A2="N" Q2A4="N" Q2A5="N" Q2A6="N" Q2A7="N" Q2A8="N" Q2A9="N" Q2A10="N" Q2A11="N" Q2A12="N" Q2A13="N"/>
<Item2B/>
<Item3A OrgFormNm="Limited Partnership"/>
<Item3B Q3B="DECEMBER"/>
<Item3C StateCD="DE" CntryNm="United States"/>
<Item5A TtlEmp="29"/>
<Item5B Q5B1="14" Q5B2="0" Q5B3="0" Q5B4="0" Q5B5="0" Q5B6="0"/>
<Item5C Q5C1="0" Q5C2="30"/>
<Item5D Q5DF1="16" Q5DF3="6391360468"/>
<Item5E Q5E1="Y" Q5E2="N" Q5E3="N" Q5E4="N" Q5E5="N" Q5E6="Y" Q5E7="N"/>
<Item5F Q5F1="Y" Q5F2A="6391360468" Q5F2B="0" Q5F2C="6391360468" Q5F2D="16" Q5F2E="0" Q5F2F="16" Q5F3="2504971810"/>
<Item5G Q5G1="N" Q5G2="N" Q5G3="N" Q5G4="Y" Q5G5="N" Q5G6="N" Q5G7="N" Q5G8="N" Q5G9="N" Q5G10="N" Q5G11="N" Q5G12="N"/>
<Item5H/>
<Item5I Q5I1="N"/>
<Item5J Q5J1="N" Q5J2="N"/>
<Item6A Q6A1="N" Q6A2="N" Q6A3="Y" Q6A4="N" Q6A5="N" Q6A6="N" Q6A7="N" Q6A8="N" Q6A9="N" Q6A10="N" Q6A11="N" Q6A12="N" Q6A13="N" Q6A14="N"/>
<Item6B Q6B1="N" Q6B3="N"/>
<Item7A Q7A1="N" Q7A2="N" Q7A3="N" Q7A4="N" Q7A5="N" Q7A6="Y" Q7A7="N" Q7A8="N" Q7A9="N" Q7A10="N" Q7A11="N" Q7A12="N" Q7A13="N" Q7A14="N" Q7A15="N" Q7A16="Y"/>
<Item7B Q7B="Y"/>
<Item8A Q8A1="N" Q8A2="N" Q8A3="N"/>
<Item8B Q8B1="N" Q8B2="N" Q8B3="N"/>
<Item8C Q8C1="Y" Q8C2="Y" Q8C3="Y" Q8C4="Y"/>
<Item8D Q8D="N"/>
<Item8E Q8E="N"/>
<Item8F/>
<Item8G Q8G1="N"/>
<Item8H Q8H1="N" Q8H2="N"/>
<Item8I Q8I="N"/>
<Item9A Q9A1A="Y" Q9A1B="Y" Q9A2A="4896054396" Q9A2B="16"/>
<Item9B Q9B1A="Y" Q9B1B="Y" Q9B2A="4896054396" Q9B2B="16"/>
<Item9C Q9C1="N" Q9C2="Y" Q9C3="N" Q9C4="N"/>
<Item9D Q9D1="N" Q9D2="N"/>
<Item9E/>
<Item9F Q9F="6"/>
<Item10A Q10A="N"/>
<Item11 Q11="N"/>
<Item11A Q11A1="N" Q11A2="N"/>
<Item11B Q11B1="N" Q11B2="N"/>
<Item11C Q11C1="N" Q11C2="N" Q11C3="N" Q11C4="N" Q11C5="N"/>
<Item11D Q11D1="N" Q11D2="N" Q11D3="N" Q11D4="N" Q11D5="N"/>
<Item11E Q11E1="N" Q11E2="N" Q11E3="N" Q11E4="N"/>
<Item11F Q11F="N"/>
<Item11G Q11G="N"/>
<Item11H Q11H1A="N" Q11H1B="N" Q11H1C="N" Q11H2="N"/>
</Part1A>
</FormInfo>
</Firm>

解决方法

我将假设您的文件将在其自己的“公司”节点中包含多个业务。

这是识别正确的子节点并从属性中提取所需信息的直接问题。

这是使用 dplyr 和 xml2 包的解决方案。我修改了您的示例输入以在 xml 文件中模拟 2 种不同的业务。

page <- read_xml('<?xml version="1.0" encoding="ISO-8859-1"?>
<IAPDFirmSECReport GenOn="2021-03-19">
<Firms>
<Firm>
<Info SECRgnCD="BRO" FirmCrdNb="133693" SECNb="801-73527" BusNm="H/2 CAPITAL PARTNERS" LegalNm="H/2 CREDIT MANAGER LP" UmbrRgstn="Y"/>
<MainAddr Strt1="680 WASHINGTON BOULEVARD" Strt2="SEVENTH FLOOR" City="STAMFORD" State="CT" Cntry="United States" PostlCd="06901-3700" PhNb="203-569-4000" FaxNb="203-569-4178"/>
<MailingAddr/>
<Rgstn FirmType="Registered" St="APPROVED" Dt="2012-03-26"/>
<NoticeFiled>
<States RgltrCd="CT" St="FILED" Dt="2015-01-08"/>
<States RgltrCd="NY" St="FILED" Dt="2017-03-02"/>
</NoticeFiled>
<Filing Dt="2020-03-26" FormVrsn="10/2017"/>
</Firm>
<Firm>
<Info SECRgnCD="BRO" FirmCrdNb="133693" SECNb="801-73527" BusNm="Company2" LegalNm="H/2 CREDIT MANAGER LP" UmbrRgstn="Y"/>
<MainAddr Strt1="WASHINGTON Ave"  City="NY" State="NY" Cntry="United States" PostlCd="12601" PhNb="212-555-4000" FaxNb="212-555-4178"/>
<MailingAddr/>
<Rgstn FirmType="Registered" St="APPROVED" Dt="2012-03-26"/>
<NoticeFiled>
<States RgltrCd="CT" St="FILED" Dt="2015-01-08"/>
<States RgltrCd="NY" St="FILED" Dt="2017-03-02"/>
</NoticeFiled>
<Filing Dt="2020-03-26" FormVrsn="10/2017"/>
</Firm>
 </Firms> </IAPDFirmSECReport>')


library(xml2)
library(dplyr)
#assuming there is 1 info node for every MainAddr node
info <- xml_find_all(page,".//Info")
addr <- xml_find_all(page,".//MainAddr")

#extract the information from the attributes
#get Name from info node
BusName <- xml_attr(info,"BusNm")

#retrieve info from all of the attributes from MainAddr node
# and bind into a datafame
addresses <- bind_rows(xml_attrs(addr))

answer <- cbind(BusName,addresses)
answer
               BusName                    Strt1         Strt2     City State         Cntry    PostlCd         PhNb        FaxNb
1 H/2 CAPITAL PARTNERS 680 WASHINGTON BOULEVARD SEVENTH FLOOR STAMFORD    CT United States 06901-3700 203-569-4000 203-569-4178
2             Company2           WASHINGTON Ave          <NA>       NY    NY United States      12601 212-555-4000 212-555-4178