我有一堆
XML文件和一个R脚本,可以将其内容读入数据框.但是,我现在得到了我想像往常一样解析的文件,但是它们的命名空间定义中有些东西不允许我通常使用XPath表达式选择它们的值.
XML文件是这样的:
xml_nons.xml
<?xml version="1.0" encoding="UTF-8"?> <XML> <Node> <Name>Name 1</Name> <Title>Title 1</Title> <Date>2015</Date> </Node> </XML>
和另外一个:
xml_ns.xml
<?xml version="1.0" encoding="UTF-8"?> <XML xmlns="http://www.nonexistingsite.com"> <Node> <Name>Name 2</Name> <Title>Title 2</Title> <Date>2014</Date> </Node> </XML>
xmlns指向的URL不存在.
我使用的R代码是这样的:
library(XML) xmlfiles <- list.files(path = ".",pattern="*.xml$",full.names = TRUE,recursive = TRUE) n <- length(xmlfiles) dat <- vector("list",n) for(i in 1:n){ doc <- xmlTreeParse(xmlfiles[i],useInternalNodes = TRUE) nodes <- getNodeSet(doc,"//XML") x <- lapply(nodes,function(x){ data.frame( Filename = xmlfiles[i],Name = xpathSApply(x,".//Node/Name",xmlValue),Title = xpathSApply(x,".//Node/Title",Date = xpathSApply(x,".//Node/Date",xmlValue) )}) dat[[i]] <- do.call("rbind",x) } xml <- do.call("rbind",dat) xml
但是,我得到的结果是:
Filename Name Title Date ./xml_nons.xml Name 1 Title 1 2015
Filename Name Title Date ./xml_nons_1.xml Name 1 Title 1 2015 ./xml_ns_1.xml Name 2 Title 2 2014
当然我可以有一个XSL从原始XML文件中删除这些命名空间,但我想有一些在R中工作的解决方案.有没有办法告诉R只是忽略XML声明中的所有内容?
我认为没有简单的方法来忽略名称空间.最好的方法是学会与他们一起生活.这个答案将使用较新的XML2包.但这同样适用于XML包解决方案.
使用
library(XML2) fname='myfile.xml' doc <- read_xml(fname) #peak at the namespaces xml_ns(doc)
第一个名称空间分配给d1.如果XPath找不到您想要的内容,最可能的原因是命名空间问题.
xpath <- "//d1:FormDef" ns <- xml_find_all(doc,xpath,xml_ns(doc)) ns
此外,您必须为路径中的每个元素执行此操作
所以为了节省打字,你可以做到
library(stringr) > xpath <- "/ODM/Study" > (xpath<-str_replace_all(xpath,'/','/d1:')) [1] "/d1:ODM/d1:Study"