簡體   English   中英

從 xml 文件中提取特定的內部節點並在 r 中構建數據幀

[英]Extracting specific internal nodes from an xml file and construct a dataframe in r

我有一個 xml 文件,我想使用XML包中的xmlToDataFrame從 R 中提取特定節點。 我可以獲得從單個節點提取數據的功能。 前任:

xml <- xmlParse("file.xml")

df <- xmlToDataFrame(getNodeSet(xml, "//lat"))

但是我想知道是否可以同時提取多個節點? 具體來說,我希望制作一個五列數據//bin_uri ,從節點中提取數據: //nucleotides//lat//lon//bin_uri//record_id來自xml的//record_id

xml文件的結構如下(只有一個record_id但是文件中有很多我需要提取):

    <record>
      <record_id>634750</record_id>
      <processid>CCSMA054-07</processid>
      <bin_uri>AAG2098</bin_uri>
      <collection_event>
        <collectors>Arctic Ecology</collectors>
          <coordinates>
            <lat>58.805</lat>
            <lon>-94.214</lon>
          </coordinates>
        <country>Canada</country>
        <province>Manitoba</province>
      </collection_event>
      <sequences>
       <sequence>
         <sequenceID>3336699</sequenceID>
         <markercode>COI-5P</markercode>
         <genbank_accession>HQ938393</genbank_accession>
         <nucleotides>CTCAGAGTTCTCACCTGGC</nucleotides>
       </sequence>
      </sequences>
    </record>

考慮簡單地使用xpathSApply()運行各種xpath表達式,然后將它們綁定到一個數據框中:

library(XML)

doc<-xmlParse("D:/Freelance Work/Scripts/BoldXML.xml")

record_id <- xpathSApply(doc, "//record/record_id", xmlValue)
bin_uri <- xpathSApply(doc, "//record/bin_uri", xmlValue)
lat <- xpathSApply(doc, "//record/collection_event/coordinates/lat", xmlValue)
lon <- xpathSApply(doc, "//record/collection_event/coordinates/lon", xmlValue)
nucleotides <- xpathSApply(doc, "//record/sequences/sequence/nucleotides", xmlValue)

df <- data.frame(record_id = unlist(record_id), 
                 bin_uri = unlist(bin_uri),                  
                 lat = unlist(lat),
                 lng = unlist(lon),
                 nucleotides = unlist(nucleotides))

或者,您可以使用XSLT來簡化原始 XML,它是一種用於重組/重新設計 XML 文件的專用語言。 雖然 R 沒有通用的 XSLT 包,但實際上所有通用語言(C#、Java、PHP、Perl、Python、VB)都維護 XSLT 庫,您甚至可以使用system()從 R 調用腳本。 更重要的是,諸如 Windows 的 PowerShell 和 Linux 的 Bash 之類的命令行程序可以運行 XSLT。

XSLT腳本(另存為 .xsl 或 .xslt)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

  <xsl:template match="/">
    <root>
      <xsl:apply-templates select="*"/>
    </root>
  </xsl:template>  

  <xsl:template match="record">
    <xsl:copy>
      <xsl:copy-of select="record_id"/>
      <xsl:copy-of select="bin_uri"/>     
      <xsl:copy-of select="collection_event/coordinates/lat"/>
      <xsl:copy-of select="collection_event/coordinates/lon"/>
      <xsl:copy-of select="sequences/sequence/nucleotides"/>
    </xsl:copy>
  </xsl:template>

</xsl:transform>

XML (轉換后)

<?xml version="1.0" encoding="utf-8"?>
<root>
  <record>
    <record_id>634750</record_id>
    <bin_uri>AAG2098</bin_uri>
    <lat>58.805</lat>
    <lon>-94.214</lon>
    <nucleotides>CTCAGAGTTCTCACCTGGC</nucleotides>
  </record>
</root>

R腳本:

result <- system('..some command line call to an external script that 
                  parses original xml and above xslt script and transforms
                  former with the latter..', intern = TRUE)

doc <- xmlParse("C:/Path/To/Transformed/XML.xml")
df <- xmlToDataFrame(getNodeSet(doc, "//record"))

與之前的答案一樣,帶有 xpath 的getNodeSet是另一種快速獲取所需值的方法。 如果每個 xpath 都有一個節點,您可以使用:

library(XML)

doc <- xmlParse("D:/Freelance Work/Scripts/BoldXML.xml")

record_id <- xmlValue(getNodeSet(doc, "//record/record_id"))
bin_uri   <- xmlValue(getNodeSet(doc, "//record/bin_uri"))
lat       <- xmlValue(getNodeSet(doc, "//record/collection_event/coordinates/lat"))
lon       <- xmlValue(getNodeSet(doc, "//record/collection_event/coordinates/lon"))
ntides    <- xmlValue(getNodeSet(doc, "//record/sequences/sequence/nucleotides"))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM