处理R中的空XML节点

时间:2014-08-17 04:59:42

标签: xml r xmlnode xml-attribute

我有以下XML文件(我缺少根节点,但编辑器不允许我 - 请假设这里有根节点):

<Indvls>
    <Indvl>
        <Info lastNm="HANSON" firstNm="LAURIE"/>
        <CrntEmps>
            <CrntEmp orgNm="ABC INCORPORATED" str1="FOURTY FOUR BRYANT PARK" city="NEW YORK" state="NY" cntry="UNITED STATES" postlCd="10036">
            <BrnchOfLocs>
                <BrnchOfLoc str1="833 NE 55TH ST" city="BELLEVUE" state="WA" cntry="UNITED STATES" postlCd="98004"/>
            </BrnchOfLocs>
            </CrntEmp>
        </CrntEmps>
    </Indvl>
    <Indvl>
        <Info lastNm="JACKSON" firstNm="SHERRY"/>
        <CrntEmps>
            <CrntEmp orgNm="XYZ INCORPORATED" str1="3411 GEORGE STREET" city="SAN FRANCISCO" state="CA" cntry="UNITED STATES" postlCd="94105">
            <BrnchOfLocs>
            </BrnchOfLocs>
            </CrntEmp>
        </CrntEmps>
    </Indvl>
</Indvls>

使用R,我想以表格的形式提取以下列: (a)来自/ Info节点的lastNm和firstNm - 始终带有值; (b)来自/ CrntEmps / CrntEmp节点的orgNm - 始终带有值;和 (c)str1,city,state from / CrntEmps / BrnchOfLocs / BrnchofLoc节点 - 可能有也可能没有值(在我的例子中,第二个实体没有办公地址)。

我的挑战是很多节点都没有BrnchOfLoc节点。我想创建一个条目,即使节点丢失(否则表是不平衡的,我在数据帧中创建时会出错)。

有什么想法或建议吗?我很感激任何投入。

附录:这是我的代码:

xmlGetNodeAttr <- function(n, xp, attr, default=NA) {
ns<-getNodeSet(n, xp)
if(length(ns)<1) {
    return(default)
} else {
    sapply(ns, xmlGetAttr, attr, default)
}
}

do.call(rbind, lapply(xmlChildren(xmlRoot(doc)), function(x) {
data.frame(
    fname=xmlGetNodeAttr(x, "//Info","firstNm",NA),
    lname=xmlGetNodeAttr(x, "//Info","lastNm",NA),
  orgname=xmlGetNodeAttr(x,"//CrntEmps/CrntEmp[1]","orgNm",NA),
    zip=xmlGetNodeAttr(x, "//CrntEmps/CrntEmp[1]/BrnchOfLocs/BrnchOfLoc[1]","city",NA)
)
}))

1 个答案:

答案 0 :(得分:2)

你应该这样做

do.call(rbind, lapply(xmlChildren(xmlRoot(doc)), function(x) {
data.frame(
    fname=xmlGetNodeAttr(x, "./Info","firstNm",NA),
    lname=xmlGetNodeAttr(x, "./Info","lastNm",NA),
    orgname=xmlGetNodeAttr(x, "./CrntEmps/CrntEmp[1]","orgNm",NA),
    zip=xmlGetNodeAttr(x, "./CrntEmps/CrntEmp[1]/BrnchOfLocs/BrnchOfLoc[1]","city",NA)
)
}))

请注意使用./而不是//。后者将搜索整个文档,忽略您lapply的当前节点。使用./将从当前x节点开始,仅查看后代。返回

        fname   lname          orgname      zip
Indvl  LAURIE  HANSON ABC INCORPORATED BELLEVUE
Indvl1 SHERRY JACKSON XYZ INCORPORATED     <NA>