处理R语言中空XML节点问题

3

我有以下的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) /CrntEmps/BrnchOfLocs/BrnchofLoc节点中的str1、city和state--可能具有值或不具有值(在我的示例中,第二个实体没有办公地址)。
我的挑战是许多节点将没有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)
)
}))

你在做什么?如何创建你的数据框架?我猜你已经写了一些 R 代码。最好也把它发布出来。 - MrFlick
我使用了你之前线程中的一个函数。 - user3808860
你可以编辑你的原始问题并将其包含在那里,这样它会更好地格式化。 - MrFlick
谢谢。已经完成了。希望现在它能够清晰可见。 - user3808860
1个回答

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>

我遇到了整个BrnchOfLocs节点和子节点(BrnchofLoc)都丢失的情况。代码在这一点上出现了问题。有什么想法吗?非常感谢您对此问题的意见。谢谢。 - user3808860
在那种情况下,它似乎完全一样。你遇到了什么“问题”? - MrFlick
好的 - 让我尝试在我的XML文件和代码中尝试几个变化,看看是否仍然遇到当前问题(只显示一行,全部为NA值)。再次感谢。 - user3808860
如果我从上面的示例中删除<BrnchOfLocs/>,它就可以正常工作。请确保您的示例数据能够重现您遇到的问题。 - MrFlick
MrFlick - 我采用了稍微不同的方法,因为我需要更多的灵活性。稍后我会发布我的解决方案。非常感谢你的帮助。 - user3808860
2
@user3808860,我认为您忘记发布您的解决方案了。 - Hack-R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接