我有一个输入xml文件.
cat sample.xml
<Text>
<p>ABC </p>
</Text>
Run Code Online (Sandbox Code Playgroud)
R脚本
library(XML)
doc = xmlTreeParse("sample.xml", useInternal = TRUE)
top<-xmlRoot(doc)
sub("<","<",top[[1]])
Run Code Online (Sandbox Code Playgroud)
我怎样才能修复上面的pblm?
错误消息:as.vector(x,"character")中的错误:无法强制将'externalptr'类型强制转换为'character'类型的向量
编辑:目标是对xml中的特定节点使用readHTMLTable()函数,该函数具有html表但是它具有xml标记(>和<)for>和<需要首先重新执行,因为readHTMLTable函数无法处理xml标记.
现在回答你真正的问题:
带编码表的sample.xml:
<Text>
<table>
<tr><td>1</td><td>2</td></tr>
<tr><td>2</td><td>8</td></tr>
<tr><td>4</td><td>32</td></tr>
</table>
</Text>
Run Code Online (Sandbox Code Playgroud)
阅读:
> library(XML)
> doc = xmlTreeParse("sample.xml", useInternal = TRUE)
> top<-xmlRoot(doc)
Run Code Online (Sandbox Code Playgroud)
转换为文字:
> table=xmlValue(top)
> table
[1] "\n<table>\n<tr><td>1</td><td>2</td></tr>\n<tr><td>2</td><td>8</td></tr>\n<tr><td>4</td><td>32</td></tr>\n</table>\n"
Run Code Online (Sandbox Code Playgroud)
现在已经准备好了readHTMLTable.无需字符串转换:
> readHTMLTable(table)
$`NULL`
V1 V2
1 1 2
2 2 8
3 4 32
Run Code Online (Sandbox Code Playgroud)
Howzat?
如果您的问题是要知道如何替换XML节点内容中的字符串,那么您可以使用sample.xml您提供的文件检查以下代码:
## Parse the XML file
doc <- xmlTreeParse("sample.xml", useInternal = TRUE)
## Select the nodes we want to update
nodes <- getNodeSet(doc, "//Text")
## For each node, apply gsub on the content of the node
lapply(nodes, function(n) {
xmlValue(n) <- gsub("ABC","foobar",xmlValue(n))
})
Run Code Online (Sandbox Code Playgroud)
哪个会给你:
R> doc
<?xml version="1.0"?>
<Text>
<p>foobar </p>
</Text>
Run Code Online (Sandbox Code Playgroud)
在这里你可以看到"ABC"被"foobar"取代.
但是,如果你尝试使用你想要实现的替换代码(替换"<"wit"<"),它显然不会起作用:
doc <- xmlTreeParse("sample.xml", useInternal = TRUE)
nodes <- getNodeSet(doc, "//Text")
lapply(nodes, function(n) {
xmlValue(n) <- gsub("<","<",xmlValue(n))
})
Run Code Online (Sandbox Code Playgroud)
会给你 :
R> doc
<?xml version="1.0"?>
<Text>
<p>ABC </p>
</Text>
Run Code Online (Sandbox Code Playgroud)
为什么?如果您正在处理XML文件,您应该知道某些字符,主要是<,>,&和"是保留的,因为它们是基本XML语法的一部分.因此,它们不能出现在节点的内容中,否则会解析因此它们被实体取代,实体是这些字符的一种编码.例如,"<"编码为"<","&"编码为"&"等.
所以在这里,节点的内容包含一个"<"字符,该字符已自动转换为他的实体"<".您尝试对代码执行的操作是替换"<" 回到"<",R很乐意为你做,但由于它是节点的文本内容,XML包将立即将其转换回"<".
所以,如果你想要实现的是转换你的字符串"< p> ABC</p>" 到新的XML节点"<p> ABC </ p>",你不能这样做.一个解决方案是解析你的文本字符串,从中检测名称和节点(这里是"p"),创建一个新节点xmlNode(),给它文本内容"ABC"并用你刚才的节点替换字符串创建.
另一种快速而又脏的方法是首先替换文件中的所有实体而不解析XML.像这样的东西:
txt <- readLines(file("sample.xml"))
txt <- gsub("<", "<", txt)
txt <- gsub(">", ">", txt)
writeLines(txt, file("sample2.xml"))
doc2 <- xmlTreeParse("sample2.xml", useInternal = TRUE)
Run Code Online (Sandbox Code Playgroud)
这使 :
R> doc2
<?xml version="1.0"?>
<Text>
<p>ABC </p>
</Text>
Run Code Online (Sandbox Code Playgroud)
但这很危险,因为如果有一个"真实的""<" 您文件中的实体,解析将失败.