处理 R 中的空 XML 节点

Posted

技术标签:

【中文标题】处理 R 中的空 XML 节点【英文标题】:Dealing with empty XML nodes in R 【发布时间】:2014-08-17 04:59:41 【问题描述】:

我有以下 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)
)
))

【问题讨论】:

你在做什么如何创建你的数据框?我假设您已经编写了一些 R 代码。也将其发布是个好主意。 我使用了你之前线程中的一个函数。 您可以编辑原始问题以将其包含在其中。格式会更好。 谢谢。做过某事。希望它现在可见且清晰。 【参考方案1】:

你应该这样做

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-ing 上的当前节点。使用./ 将从当前的x 节点开始,并且只查看后代。这返回

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

【讨论】:

我正面临整个 BrnchOfLocs 节点和子节点 (BrnchofLoc) 丢失的情况。这段代码在那时遇到了问题。想法?我非常感谢您在这个问题上的意见。谢谢。 在这种情况下,它的工作方式似乎完全相同。你遇到了什么“问题”? 好吧 - 让我在我的 XML 文件和代码中尝试一些变体,看看我是否仍然遇到当前问题(只显示一行,全部带有 NA 值)。再次感谢。 好吧,如果我从上面的示例中取出&lt;BrnchOfLocs/&gt;,它就可以正常工作。确保您的示例数据重现了您遇到的问题。 @user3808860 我想你忘了发布你的解决方案

以上是关于处理 R 中的空 XML 节点的主要内容,如果未能解决你的问题,请参考以下文章

XML反序列化处理具有默认值的空标签

R中的XML解析 - 子节点属性的递归体面

R - 获取 XML 节点

通过 Xpaths 从 R 中的文件中删除或过滤 XML 节点

使用 R 的 xmlEventParse 存储特定的 XML 节点值

节点为数组中的空值分配多少内存