在 XMLNodeSet(XML 包)上使用 getNodeSet
Using getNodeSet on XMLNodeSet (XML package)
我无法将 R XML 包用于我想到的特定应用程序。考虑以下示例文档。我有兴趣在第一个 a 节点内获取 b 中的信息。但是我的问题(应用程序)的性质是,我首先 需要 识别文档中的所有 a 节点,然后对该节点集进行子集化以获取第一个 a 节点,然后获取 b节点。第一步很简单:
doc <- "
<div></div>
<a id='1'><b id='3'>text1</b></a>
<a id='2'><b id='4'>text2</b></a>
"
parsed <- htmlParse(doc)
step1 <- getNodeSet(parsed, "//a")
> step1
[[1]]
<a id="1">
<b id="3">text1</b>
</a>
[[2]]
<a id="2">
<b id="4">text2</b>
</a>
attr(,"class")
[1] "XMLNodeSet"
这产生了预期的结果。我的应用程序的下一步是从第一个 a 节点中提取 b 节点。如果我在 step1[[1]] 上使用 getNodeSet,我会从 step1 节点集中的两个节点获取 b 节点。
step2 <- getNodeSet(step1[[1]], "//b")
step2
[[1]]
<b id="3">text1</b>
[[2]]
<b id="4">text2</b>
attr(,"class")
[1] "XMLNodeSet"
我发现我可以使用 XPath "b" 来获取此示例中的信息,但最终我需要“//b”才能在这里工作。我理解 XML 包的工作方式,我不认为这种行为是错误,而是引用本文档的 C 级表示的结果。有什么办法可以通过任何方式实现这个 "two-step" 过程吗?我基本上希望 step[[1]] 像新文档一样工作。
有很多方法可以用来实现你想要的。首先你可以调整你的 XPATH:
doc <- "
<div></div>
<a id='1'><b id='3'>text1</b></a>
<a id='2'><b id='4'>text2</b></a>
"
parsed <- htmlParse(doc)
parsed["//a[1]/b"]
> parsed["//a[1]/b"]
[[1]]
<b id="3">text1</b>
attr(,"class")
[1] "XMLNodeSet"
如果您需要从 step1
开始工作,您可以在 XPATH 中使用相对引用:
step1 <- getNodeSet(parsed, "//a")
getNodeSet(step1[[1]], "./b")
> getNodeSet(step1[[1]], "./b")
[[1]]
<b id="3">text1</b>
attr(,"class")
[1] "XMLNodeSet"
要像处理新的 XML 文档一样使用 step1[[1]]
,有两种方法可能适合:
mydoc2 <- xmlParse(saveXML(step1[[1]]))
> mydoc2["//b"]
[[1]]
<b id="3">text1</b>
attr(,"class")
[1] "XMLNodeSet"
可能更好的是:
mydoc3 <- xmlDoc(step1[[1]])
> mydoc3["//b"]
[[1]]
<b id="3">text1</b>
attr(,"class")
[1] "XMLNodeSet"
我无法将 R XML 包用于我想到的特定应用程序。考虑以下示例文档。我有兴趣在第一个 a 节点内获取 b 中的信息。但是我的问题(应用程序)的性质是,我首先 需要 识别文档中的所有 a 节点,然后对该节点集进行子集化以获取第一个 a 节点,然后获取 b节点。第一步很简单:
doc <- "
<div></div>
<a id='1'><b id='3'>text1</b></a>
<a id='2'><b id='4'>text2</b></a>
"
parsed <- htmlParse(doc)
step1 <- getNodeSet(parsed, "//a")
> step1
[[1]]
<a id="1">
<b id="3">text1</b>
</a>
[[2]]
<a id="2">
<b id="4">text2</b>
</a>
attr(,"class")
[1] "XMLNodeSet"
这产生了预期的结果。我的应用程序的下一步是从第一个 a 节点中提取 b 节点。如果我在 step1[[1]] 上使用 getNodeSet,我会从 step1 节点集中的两个节点获取 b 节点。
step2 <- getNodeSet(step1[[1]], "//b")
step2
[[1]]
<b id="3">text1</b>
[[2]]
<b id="4">text2</b>
attr(,"class")
[1] "XMLNodeSet"
我发现我可以使用 XPath "b" 来获取此示例中的信息,但最终我需要“//b”才能在这里工作。我理解 XML 包的工作方式,我不认为这种行为是错误,而是引用本文档的 C 级表示的结果。有什么办法可以通过任何方式实现这个 "two-step" 过程吗?我基本上希望 step[[1]] 像新文档一样工作。
有很多方法可以用来实现你想要的。首先你可以调整你的 XPATH:
doc <- "
<div></div>
<a id='1'><b id='3'>text1</b></a>
<a id='2'><b id='4'>text2</b></a>
"
parsed <- htmlParse(doc)
parsed["//a[1]/b"]
> parsed["//a[1]/b"]
[[1]]
<b id="3">text1</b>
attr(,"class")
[1] "XMLNodeSet"
如果您需要从 step1
开始工作,您可以在 XPATH 中使用相对引用:
step1 <- getNodeSet(parsed, "//a")
getNodeSet(step1[[1]], "./b")
> getNodeSet(step1[[1]], "./b")
[[1]]
<b id="3">text1</b>
attr(,"class")
[1] "XMLNodeSet"
要像处理新的 XML 文档一样使用 step1[[1]]
,有两种方法可能适合:
mydoc2 <- xmlParse(saveXML(step1[[1]]))
> mydoc2["//b"]
[[1]]
<b id="3">text1</b>
attr(,"class")
[1] "XMLNodeSet"
可能更好的是:
mydoc3 <- xmlDoc(step1[[1]])
> mydoc3["//b"]
[[1]]
<b id="3">text1</b>
attr(,"class")
[1] "XMLNodeSet"