![](/img/trans.png)
[英]r - extracting nodes from xml file using xml2 while keeping original sequence of nodes
[英]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.