我需要将XML文件解析为简单的数据框。问题是文件很复杂。多个作者可以与一个专利相关联,专利可以使用多个标签,而作者 - 机构协会不一定是一对一的。还有什么?名称分为两个字段 - 名称和姓氏。我需要检索那些没有让作者的名字混淆的东西。
与此处描述的问题(How to transform XML data into a data.frame?)不同,协会是3方式:作者/发明者对专利,专利对标签,作者对机构。其次,机构并不总是以同样的方式报道。如果所有作者都隶属于一个机构,那么该机构只会在" aff"标签。 (见下面的例子)。每个项目的多个作者的常见问题仍然存在。
挑战也类似于这里的平衡,(Parsing XML file with known structure and repeating elements),但正如你所看到的,布局是完全不同的,轻轻地说。
制作数据样本
<patents>
<patent patno="101103062330">
<office coden="EPO" short="Eur. Pat. Office"> European Office </office>
<volume>80 </volume>
<issue printdate="2009-12-00">6 </issue>
<numpages>13 </numpages>
<section code="A-2D"> Filtering </section>
<patno>101103062330 </patno>
<title> trapping plastic waste </title>
<authgrp>
<author>
<givenname>Endo </givenname>
<surname>Wake </surname>
</author>
<author>
<givenname>C. </givenname>
<surname>Morde </surname>
</author>
<aff> University of M, USA </aff>
</authgrp>
<history>
<received date="2009-07-01"/>
<published date="2009-07-30"/>
</history>
<tag tagyr="2009">
<tagcode>B1.C2.B5 </tagcode>
<tagcode>F4.65.F6 </tagcode>
</tag>
<assignment>
<assigndate date="2009"/>
<rightholder> university of M </rightholder>
</assignment>
</patent>
<patent patno="101103062514">
<office coden="EPO" short="Eur. Pat. Office"> European Office </office>
<issue printdate="2009-12-00">6 </issue>
<numpages>15 </numpages>
<section code="A-3D"> structure and dynamics </section>
<patno>101103062514 </patno>
<title> separation of cascades and photon emission </title>
<authgrp>
<author affref="a1 a2">
<givenname>L. </givenname>
<surname>Slabsky </surname>
</author>
<author affref="a1">
<givenname>D. </givenname>
<surname>Volosvyev </surname>
</author>
<author affref="a3">
<givenname>G. </givenname>
<surname>Nonpl </surname>
</author>
<aff affid="a1"> Institute of Physics,Russia </aff>
<aff affid="a2"> Physics Institute, St. Petersburg </aff>
<aff affid="a3">Technische Universiteit, Dresden </aff>
</authgrp>
<history>
<received date="2009-01-11"/>
<published date="2009-01-31"/>
</history>
<tag tagyr="2009">
<tagcode>A1.B2.C3 </tagcode>
</tag>
<assignment>
<assigndate date="2009"/>
<rightholder> Physics Inst </rightholder>
</assignment>
</patent>
</patents>
我想从这个xml文件中获取三个表。
第一个简单地将作者/发明者与他们的专利相匹配,第二个匹配专利到标签,而第三个匹配发明人/作者到机构:
表1样本
`Patent Author1 Author2 Author3
101103062330 Endo Wake C. Morde
101103062514 L. Slabsky D.Volosyev G. Nonpl`
长表格格式也很好。
`Patent Author
101103062330 Endo Wake
101103062330 C. Morde
101103062514 L. Slabsky
101103062514 D.Volosyev
101103062514 G. Nonpl`
表2样本
`Patent Tag
101103062330 B1.C2.B5
101103062330 F4.65.F6
101103062514 A1.B2.C3`
表3样本
`Author Institution
Endo Wake University of M
C. Morde University of M
L. Slabsky Institute of Physics,Russia
D.Volosyev Physics Institute, St. Petersburg
G. Nonpl Technische Universiteit, Dresden`
我尝试使用:
xmlfile <- xmlInternalTreeParse("filename.xml", useInternal = T)
nodes <- getNodeSet(xmlfile, "//patent")
authors <- lapply(nodes, xpathSApply, ".//author", xmlValue)
patent <- sapply(nodes, xpathSApply, ".//patent", xmlValue)
没有运气。它不会解析组内的作者姓名。
我也尝试过:
dt1 <- ldply(xmlToList(xmlfile), data.table)
没有运气。我得到一张第1栏的表格,说#34;专利&#34;和第2栏中的各种数据。
我是XML包的新手,所以我很感激一些支持。
答案 0 :(得分:1)
试试这个。
lapply(
getNodeSet(patents, "//patent"),
function(patent){
data.frame(
patent = xmlAttrs( patent )[["patno"]],
xmlToDataFrame(
nodes = getNodeSet(patent,".//*[contains(local-name(), 'author')]")
),
stringsAsFactors = FALSE
)
}
)
lapply(
getNodeSet(patents, "//patent"),
function(patent){
data.frame(
patent = xmlAttrs( patent )[["patno"]],
tag = xpathSApply(
patent,
".//tagcode",
xmlValue
),
stringsAsFactors = FALSE
)
}
)
我会把加入作为家庭作业。
lapply(
getNodeSet(patents, "//authgrp"),
function(autg){
aff_df <- do.call(
rbind,
c(
xpathApply(
autg,
".//aff[@affid]", # get only those with affid attr
function(aff){
data.frame(
aff_id = xmlAttrs(aff)[["affid"]],
institution = xmlValue(aff)
)
}
),
xpathApply(
autg,
".//aff[not(@affid)]", # get only those without affid
function(aff){
data.frame(
aff_id = NA,
institution = xmlValue(aff)
)
}
)
)
)
authors <- getNodeSet( autg, "./author")
aut_df <- xmlToDataFrame( nodes = authors )
aut_df$aff_id <- lapply(
1:length(authors)
,function(i){
if(!is.null(xmlAttrs(authors[[i]])[["affref"]])){
xmlAttrs(authors[[i]])[["affref"]]
} else {
NA
}
}
)
list(aff_df,aut_df)
}
)