使用XML关联子节点和父节点的值

使用XML关联子节点和父节点的值,xml,r,Xml,R,当使用R的XML包时,如何保存与该节点关联的特定节点的数据,例如在同一列表中?我试图将从web上获取的数据放入一个数据框中,并将相关信息分组成行。有一些元素没有类属性来区分它们,每个相关组(数据帧的行)中可能有一个或两个 下面是我保存为html\u example.html的一些html示例 <!DOCTYPE html> <html> <body> <div class="foo"> <div

当使用R的XML包时,如何保存与该节点关联的特定节点的数据,例如在同一列表中?我试图将从web上获取的数据放入一个数据框中,并将相关信息分组成行。有一些
元素没有类属性来区分它们,每个相关组(数据帧的行)中可能有一个或两个

下面是我保存为
html\u example.html
的一些html示例

<!DOCTYPE html>
<html>
    <body>
        <div class="foo">
            <div class="fooname">Name of 1st foo</div>
            <span>1st span in 1st foo</span>
            <span>2nd span in 1st foo</span>
        </div>

        <div class="foo">
            <div class="fooname">Name of 2nd foo</div>
            <span>Only 1 span in 2nd foo</span>
        </div>
    </body>
</html>

第一富的名字
第一富第一跨
第一富第二跨
第二富的名字
第二个foo中只有一个span
以下是当前解析代码和输出:

library(XML)

html <- readLines("html_example.html")
parse <- htmlParse(html)

fooname <- xpathSApply(parse, "//div[@class='foo']/div[@class='fooname']"
    , xmlValue)
print(fooname)

    # > print(fooname)
    # [1] "Name of 1st foo" "Name of 2nd foo"

span <- xpathSApply(parse, "//div[@class='foo']/span"
    , xmlValue)
print(span)

    # >     print(span)
    # [1] "1st span in 1st foo"    "2nd span in 1st foo"    "Only 1 span in 2nd foo"
库(XML)

html您可以对每个感兴趣的节点应用一个函数(
div[class=“foo”]
。一个简单的示例以每个节点为例,将xmlValue应用于
div class=“fooname”
span
子节点。然后,它将这些值作为
data.frame
返回。您可以将结果data.frames绑定在一起以获得所需的结果:

'<!DOCTYPE html>
<html>
    <body>
        <div class="foo">
            <div class="fooname">Name of 1st foo</div>
            <span>1st span in 1st foo</span>
            <span>2nd span in 1st foo</span>
        </div>

        <div class="foo">
            <div class="fooname">Name of 2nd foo</div>
            <span>Only 1 span in 2nd foo</span>
        </div>
    </body>
</html>' -> appData
doc <- htmlParse(appData)
myFunc <- function(x){
  div <- xpathSApply(x, "./div[@class='fooname']", fun = xmlValue)
  span <- xpathSApply(x, "./span", fun = xmlValue)
  data.frame(FooNames = div, Span1 = span[1], Span2 = span[2])
}
res <- doc["//*/div[@class='foo']", fun = myFunc]

> do.call(rbind, res)
FooNames                  Span1               Span2
1 Name of 1st foo    1st span in 1st foo 2nd span in 1st foo
2 Name of 2nd foo Only 1 span in 2nd foo                <NA>
'
第一富的名字
第一富第一跨
第一富第二跨
第二富的名字
第二个foo中只有一个span
'->appData

doc我喜欢使用
span[2]
适当地输入值或NA。
doc[“/*/div[@class='foo']”,fun=myFunc]
xpathApply(doc,“//*/div[@class='foo']”,fun=myFunc)
[/code>是调用
getNodeSet
的语法糖,如
getAnywhere([.XMLInternalDocument”)所示
谢谢。我也用
xpathApply
使用了这一行。我也曾在其他时间用
xpathApply
getNodeSet
进行过实验,但很难看出其中的区别。有什么提示吗?请参阅我的
FooNames <- c(fooname[1], fooname[2])
Span1 <- c(span[1], span[3])
Span2 <- c(span[2], NA)
df <- data.frame(FooNames, Span1, Span2, stringsAsFactors = FALSE)
df

    # > df
    #          FooNames                  Span1               Span2
    # 1 Name of 1st foo    1st span in 1st foo 2nd span in 1st foo
    # 2 Name of 2nd foo Only 1 span in 2nd foo                <NA>
'<!DOCTYPE html>
<html>
    <body>
        <div class="foo">
            <div class="fooname">Name of 1st foo</div>
            <span>1st span in 1st foo</span>
            <span>2nd span in 1st foo</span>
        </div>

        <div class="foo">
            <div class="fooname">Name of 2nd foo</div>
            <span>Only 1 span in 2nd foo</span>
        </div>
    </body>
</html>' -> appData
doc <- htmlParse(appData)
myFunc <- function(x){
  div <- xpathSApply(x, "./div[@class='fooname']", fun = xmlValue)
  span <- xpathSApply(x, "./span", fun = xmlValue)
  data.frame(FooNames = div, Span1 = span[1], Span2 = span[2])
}
res <- doc["//*/div[@class='foo']", fun = myFunc]

> do.call(rbind, res)
FooNames                  Span1               Span2
1 Name of 1st foo    1st span in 1st foo 2nd span in 1st foo
2 Name of 2nd foo Only 1 span in 2nd foo                <NA>