2014-05-15 27 views
0

我對解析XML文件有疑問。然後我把我的函數和一個示例XML文件。 我的問題是:在這個文件中,我可以毫無問題地解析子節點「item」和子節點「tag」,但是當我嘗試解析子節點prop時,我得到一個包含所有值的單個字符串。 XML解析函數不區分它們,因爲它們都具有相同的標籤「prop」。我需要的子節點值存儲在data.frame中的單獨列中,有沒有辦法做到這一點?解析R中的XML文件,其中包含具有相同標記的所有值的子節點

非常感謝你

我的功能:

PARSE_INVENTORY_items<-function(DF_DEVICE_IDE_value, URL_DEVICE_value){ 
    require(XML) 
    require(RCurl) 
    host<-URL_DEVICE_value 
    device<-"/devices/" 
    ID_devices<-DF_DEVICE_IDE_value[1,1] 

    inventory<-"/inventory" 
    start_device<-"/start" 

    FULL_url<-paste(host, device, ID_devices, inventory, sep="") 
    FULL_url_start<-paste(host, device, ID_devices, start_device, sep="") 

    URL_inventory<-gsub(" ","", FULL_url, fixed=TRUE) 
    URL_start_device<-gsub(" ","", FULL_url_start, fixed=TRUE) 

    httpGET(URL_start_device) 

    XML_inventory_exists = url.exists(URL_inventory) 
    # Regular HTTP 
    if(XML_inventory_exists) { 
    inventory = getURL(URL_inventory) 
    inventory_xml <- xmlInternalTreeParse(inventory) 
    items <- getNodeSet(inventory_xml,"//data/inventory/items/item") 
    DataFrame_inventory_items <- xmlToDataFrame(items) 

    items_tags<-getNodeSet(inventory_xml, "//data/inventory/items/item/tags/tag") 
    DataFrame_inventory_tags_subnode <- xmlToDataFrame(items_tags) 

    #items_tags_props<-getNodeSet(inventory_xml, "//data/inventory/items/item/tags/tag/props/prop") 
    #DataFrame_inventory_props_subnode_tag <- xmlToDataFrame(items_tags_props) 

    DataFrame_inventory_items<-cbind(DataFrame_inventory_items,DataFrame_inventory_tags_subnode) 
    #aux<-DataFrame_inventory_items 
    #DataFrame_inventory_items<-subset(DataFrame_inventory_items, select=(-tags)) 
    return(DataFrame_inventory_items) 
    } 
} 

XML文件的示例

<?xml version="1.0" encoding="UTF-8"?> 
<inventory> 
    <type>inventory</type> 
    <ts>1396964708000</ts> 
    <status>OK</status> 
    <msg-version>2.0.0</msg-version> 
    <op>inventory</op> 
    <data> 
     <advanNetId>AdvanNet-instance-00:26:b9:08:cd:e1-3161</advanNetId> 
     <deviceId>adrd1</deviceId> 
     <inventory> 
      <class>INVENTORY</class> 
      <deviceId>adrd1</deviceId> 
      <timeWindow>2500</timeWindow> 
      <items> 
       <item> 
        <class>READ_EVENT</class> 
        <epc>00000000000000000000A200</epc> 
        <ts>1396964708122</ts> 
        <deviceId>adrd1</deviceId> 
        <tags> 
         <tag> 
          <class>CONTEXT_TAG_DATA</class> 
          <hexepc>00000000000000000000A200</hexepc> 
          <props> 
           <prop>RF_PHASE:154</prop> 
           <prop>READ_COUNT:1</prop> 
           <prop>RSSI:-55</prop> 
           <prop>TIME_STAMP:1396964708122</prop> 
           <prop>ANTENNA_PORT:1</prop> 
          </props> 
         </tag> 
        </tags> 
        <tag-rssi>-55.0</tag-rssi> 
        <tag-readcount>1</tag-readcount> 
        <tag-phase>154.0</tag-phase> 
       </item> 
      </items> 
     </inventory> 
    </data> 
</inventory> 
+0

您的「示例XML文件」不是XML - 項目,庫存等沒有結束標籤。請修改您的問題以更正該問題。 – jlhoward

+0

真的,很抱歉,XML非常長,我只放了一部分。完成。 – Alex

回答

1

所以你的XML仍然沒有很好地形成(缺少結束標記爲<items>,但足夠接近以便可用

下面的代碼創建一個數據幀來自<tags>元素的內容,每個<tag>元素具有1行,並且具有<class>,<hexepc>和每個<prop>元素的列。來自不同<prop>元素的列名稱將從文本中解析出來(如此,RF_PHASEREAD_COUNT等)。請注意,如果每個<tag>具有相同的<props>,則此功能正常。

在此示例中,您提供(更正)的xml被稱爲xml.text

library(XML) 
xml <- xmlInternalTreeParse(xml.text,useInternalNodes=T) 

# add a few extra tag nodes - you have this already 
tags <- xml["//data/inventory/items/item/tags"] 
tag <- xml["//data/inventory/items/item/tags/tag"] 
addChildren(node=tags[[1]],xmlClone(tag[[1]])) 
addChildren(node=tags[[1]],xmlClone(tag[[1]])) 
addChildren(node=tags[[1]],xmlClone(tag[[1]])) 

# this is where you start 
tags <- xml["//data/inventory/items/item/tags/tag"] 
result <- do.call(rbind,lapply(tags,function(tag){ 
    class <- xmlValue(tag["class"][[1]]) 
    hexepc <- xmlValue(tag["hexepc"][[1]]) 
    props <- sapply(tag["props"]$props["prop"],xmlValue) 
    props <- strsplit(props,":") 
    props <- setNames(sapply(props,function(x)x[2]),sapply(props,function(x)x[1])) 
    c(class=class,hexepc=hexepc,props) 
})) 
result <- data.frame(result) 
#    class     hexepc RF_PHASE READ_COUNT RSSI TIME_STAMP ANTENNA_PORT 
# 1 CONTEXT_TAG_DATA 00000000000000000000A200  154   1 -55 1396964708122   1 
# 2 CONTEXT_TAG_DATA 00000000000000000000A200  154   1 -55 1396964708122   1 
# 3 CONTEXT_TAG_DATA 00000000000000000000A200  154   1 -55 1396964708122   1 
# 4 CONTEXT_TAG_DATA 00000000000000000000A200  154   1 -55 1396964708122   1 
+0

非常感謝你,你幫了我很多:)(我在XML中添加了缺失標籤) – Alex

相關問題