【问题标题】:How to parse USER_DEFINED XML data with R如何使用 R 解析 USER_DEFINED XML 数据
【发布时间】:2022-01-06 17:40:22
【问题描述】:

我有一个带有 USER_DEFINED 参数的 XML 文件,我正在尝试解析它。这是 XML 文档的示例。

         <userDefinedParameters>
           <USER_DEFINED parameter="P1">LEFT</USER_DEFINED>
           <USER_DEFINED parameter="P2">RIGHT</USER_DEFINED>
           <USER_DEFINED parameter="P3">1234</USER_DEFINED>
           <USER_DEFINED parameter="P4">5678</USER_DEFINED>
         </userDefinedParameters>
       </data>
     </segment>
   </body>
</head>

我可以使用XML 包和xpathApply 解析出该文件中的所有数据。但是,我无法通过这种方式提取 USER_DEFINED 参数值。

由于 XML 中有几条记录,我想获取所有 P1、P2 等,因为我使用 xpathApply 获取其他字段。 document 声明所有 USER_DEFINED 参数都是“参数”和“值”,所以我认为我需要拉为 c('parameter', 'value'),但我不知道如何使用 XML 来做到这一点。

我看过this SO page,它有很大帮助,但没有回答这个问题。

感谢您的任何/所有帮助。

更新了所需的输出以及我尝试获取数据的方式。请注意,以下代码无法正常工作。

当前xpathApply 使用获取userDefinedParameters 部分中的所有USER_DEFINED 行。如果我更改为xpathApply(data, "//USER_DEFINED"), xmlValue),那么我将获得所有值,但与参数名称无关。我需要xpathApply(data, "//USER_DEFINED/P1"), xmlValue) 之类的东西,但显然这行不通。

Library(XML)
fileName <- "./file.xml"
data     <- xmlParse(fileName)
xml_data <- xmlToList(data)
p1 <- xpathApply(data, "//USER_DEFINED")
p2 <- xpathApply(data, "//USER_DEFINED")

# View(p1)
#     "P1"
#     LEFT
#     LEFT
#    RIGHT

# View(p2)
#     "P2"
#    RIGHT
#    RIGHT
#     LEFT
# ...

【问题讨论】:

    标签: r xml parsing


    【解决方案1】:

    如果您喜欢使用 XML 包,可以使用 sapply 中的 xmlAttrs 函数

    text <-' <head> <body> <segment>
     <data>
     <userDefinedParameters>
               <USER_DEFINED parameter="P1">LEFT</USER_DEFINED>
               <USER_DEFINED parameter="P2">right</USER_DEFINED>
               <USER_DEFINED parameter="P3">1234</USER_DEFINED>
               <USER_DEFINED parameter="P4">5678</USER_DEFINED>
             </userDefinedParameters>
           </data>
         </segment>
       </body>
    </head>'
    
    library(XML)
    #read the document
    doc <- xmlRoot(xmlParse(text))
    
    #parse out the USER Defined nodes
    # in this example there are 4 nodes
    nodes<-xpathApply(doc, ".//userDefinedParameters/USER_DEFINED")
    
    #step through each of the found nodes
    # xmlAttrs is not a vectorized function thus requiring a loop
    attributes <- sapply(nodes, function(n) {
       #extract the attribute from each node
       # if there was more than 1 attribute this will need updating
       xmlAttrs(unlist(n)) })
    
    #get values from each node
    values<-xmlValue(nodes)
    
    data.frame(attributes, values)
    #   attributes values
    # 1         P1   LEFT
    # 2         P2  right
    # 3         P3   1234
    # 4         P4   5678
    

    【讨论】:

    • 这只会让我得到参数名称。我更新了我的帖子以显示我如何尝试获取数据;我希望这会有所帮助。
    • 这很好用,谢谢@Dave2e。我不明白".//userDefinedParameters/USER_DEFINED" 中的点或内联函数中发生了什么。你能解释一下这些吗?
    • 前面的点是 Xpath 从当前节点而不是全局搜索。这里可能不需要,但最好是更加安全。解释见代码中的 cmets。
    • 感谢 cmets - 帮助很大。
    【解决方案2】:

    使用xml2 库,您可以使用xml_attr()parameter 的节点获取值。

    类似这样的:

    library(xml2)
    
    x <- read_xml('<userDefinedParameters>
           <USER_DEFINED parameter="P1">LEFT</USER_DEFINED>
           <USER_DEFINED parameter="P2">right</USER_DEFINED>
           <USER_DEFINED parameter="P3">1234</USER_DEFINED>
           <USER_DEFINED parameter="P4">5678</USER_DEFINED>
         </userDefinedParameters>')
    
    dataset <- data.frame(user_defined = x %>% 
                                           xml_find_all("//USER_DEFINED") %>%
                                           xml_text(),
                          parameter = x %>% 
                                        xml_find_all("//USER_DEFINED") %>%
                                        xml_attr("parameter"))
    

    结果为@​​987654325@:

      user_defined parameter
    1         LEFT        P1
    2        right        P2
    3         1234        P3
    4         5678        P4
    

    【讨论】:

    • 如果可以的话,我会尝试使用 XML 包 - 封闭系统 - 必要时我会让我迁移到 xml2。
    猜你喜欢
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 2017-12-15
    • 1970-01-01
    相关资源
    最近更新 更多