问题描述
我对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")