R:从深层嵌套的XML文件中将XML节点值提取到数据框中

时间:2016-09-29 03:57:06

标签: r xml

我正在尝试从他们的数据库中的xml FDA标签中提取成分列表。不知何故,我无法获得getNodeSet函数来生成适当的节点列表。

问题:如何修复代码以便能够提取成分名称的值。

这是不起作用的代码,它在getNodeSet函数处中断,给出0长度列表。我在[{3}}和其他许多人没有运气的情况下尝试了[优雅的提议]解决方案。

library(XML)
URL <- "http://www.accessdata.fda.gov/spl/data/e9b9a189-d9e3-42e3-b41c-846a94ebeb37/e9b9a189-d9e3-42e3-b41c-846a94ebeb37.xml"
xmlDocu <- xmlParse(URL)
xmlIngredients <- getNodeSet(xmlDocu, "//ingredient/ingredientSubstance/name")
Ingredients <- xmlSApply(xmlIngredients, function(x) xmlSApply(x, xmlValue))
dfIngredients <- data.frame(t(Ingredients),row.names=NULL)

这是深度嵌套的xml文件的一部分内容:

              <ingredient classCode="ACTIB">
                   <quantity>
                      <numerator value="160" unit="mg"/>
                      <denominator value="5" unit="mL"/>
                   </quantity>
                   <ingredientSubstance>
                      <code code="362O9ITL9D" codeSystem="2.16.840.1.113883.4.9"/>
                      <name>Acetaminophen</name>
                      <activeMoiety>
                         <activeMoiety>
                            <code code="362O9ITL9D" codeSystem="2.16.840.1.113883.4.9"/>
                            <name>acetaminophen</name>
                         </activeMoiety>
                      </activeMoiety>
                   </ingredientSubstance>
                </ingredient>
                <ingredient classCode="IACT">
                   <ingredientSubstance>
                      <code code="3QPI1U3FV8" codeSystem="2.16.840.1.113883.4.9"/>
                      <name>BUTYLPARABEN</name>
                   </ingredientSubstance>
                </ingredient>

1 个答案:

答案 0 :(得分:3)

我相信您的问题与xml文件中定义的命名空间有关。有两种方法可以解决这个问题。我更喜欢使用xml2包并去掉命名空间,然后解析文件:

library(xml2)

URL <- "http://www.accessdata.fda.gov/spl/data/e9b9a189-d9e3-42e3-b41c-846a94ebeb37/e9b9a189-d9e3-42e3-b41c-846a94ebeb37.xml"
xmlDocu <- read_xml(URL)
#find namespace
ns<-xml_ns(xmlDocu)

#I find it easier to strip the name space and use accordingly
xml_ns_strip(xmlDocu)
xml_find_all(xmlDocu, "//ingredient")
xml_text(xml_find_all(xmlDocu, "//ingredient/ingredientSubstance/name"))

我发现rvest和xml2的语法比XML包更容易使用。