R-获取XML节点

问题描述

我对XML节点有疑问。

我想替换Excel文件中的值和公式,因此,首先,我使用file.rename()将其更改为zip文件,然后,我处理zip文件的XML文件。 您可以在/xl/worksheets/sheet1.xml中找到XML,以替换,我编写了以下代码行:

library(XML)

### Change excel to zip
data_path <- "Untitled 1.xlsx"

file.rename(data_path,"Untitled 1.zip")

dir.create("Untitled 1")
utils::unzip("Untitled 1.zip",exdir = "Untitled 1")

### Read XML file
doc <- xmlTreeParse("Untitled 1/xl/worksheets/sheet1.xml",useInternal = TRUE)

#### Select the nodes we want to update
nodes <- getNodeSet(doc,"/worksheet")
nodes <- getNodeSet(doc,"/worksheet/sheetData")

# > list()
# > list()

当我得到节点时,它们都返回空白列表节点。它与getNodeSet(doc,"/")一起使用,Xpath表达式为/,它返回具有length = 1的列表。我不明白为什么这么做? XML文件有什么问题?我刚刚在https://www.freeformatter.com/xpath-tester.html中进行了测试,如果Xpath表达式为/worksheet/worksheet/sheetData

,它仍然会返回正确的结果

您能解释一下问题是什么吗?谢谢。

我在here中附加了excel文件输出zip文件和XML文件

解决方法

您的文档在根“工作表”节点中具有默认名称空间。 XML库需要使用默认命名空间进行命名。你可以做这样的事情

# name the namespaces
ns <- c(ns="http://schemas.openxmlformats.org/spreadsheetml/2006/main",r="http://schemas.openxmlformats.org/officeDocument/2006/relationships")

# use the ns= namespace in the xpath
getNodeSet(doc,"/ns:worksheet",namespaces = ns)
getNodeSet(doc,"/ns:worksheet/ns:sheetData",namespaces = ns)

我知道使用xml2,如果您不想打扰默认名称空间,就可以删除它。你可以做

library(xml2)
doc <- xml_ns_strip(read_xml("sheet1.xml"))
xml_find_all(doc,"/worksheet")
xml_find_all(doc,"/worksheet/sheetData")