<StudyFieldsResponse>
<StudyFieldsList>
<StudyFields Rank="2">
<FieldValues Field="id">
<FieldValue>327635</FieldValue>
</FieldValues>
<FieldValues Field="Gender">
<FieldValue>Male</FieldValue>
<FieldValue>Female</FieldValue>
</FieldValues>
<FieldValues Field="code">
<FieldValue>55905</FieldValue>
</FieldValues>
</StudyFields>
<StudyFields Rank="3">
<FieldValues Field="id">
<FieldValue>555828</FieldValue>
</FieldValues>
<FieldValues Field="Gender">
<FieldValue>Male</FieldValue>
</FieldValues>
<FieldValues Field="code">
<FieldValue>55407-1139</FieldValue>
<FieldValue>77030</FieldValue>
<FieldValue>90901</FieldValue>
<FieldValue>23144</FieldValue>
</FieldValues>
</StudyFields>
</StudyFieldsList>
</StudyFieldsResponse>
我有上面的.xml
檔案。id
為了提取、Gender
和code
記錄,我將其決議如下。
library(XML)
dat <- xmlParse(file = "example.xml")
final_dat <- xmlToDataFrame(nodes = xmlChildren(xmlRoot(dat)[["StudyFieldsList"]]))
names(final_dat) <- c("id", "Gender", "code")
> final_dat
id Gender code
1 327635 MaleFemale 55905
2 555828 Male 55407-1139770309090123144
但是,請注意,對于第一行,有 2Gender
秒,男性和女性。同樣,對于第二個,也有超過 1 code
s。如何擴展我的 data.frame 以使 data.frame 包含每個唯一、和組合的id
唯一Gender
行code
?
> final_dat_expanded
id Gender code
1 327635 Male 55905
2 327635 Female 55905
3 555828 Male 55407-1139
4 555828 Male 77030
5 555828 Male 90901
6 555828 Male 23144
uj5u.com熱心網友回復:
對于復雜的嵌套 XML,請考慮XSLT,這是一種專門用于轉換 XML 檔案的語言。在 Unix (Mac/Linux) 上,R 可以通過system
呼叫開源實用程式xsltproc
. 在 Windows 上,R 可以運行引數化的 PowerShell 腳本。
具體來說,下面的 XSLT 以代碼下的最低級別 FieldValue 為目標,然后有條件地檢索祖先節點的 id 和性別,映射到所有性別節點for-each
。
XSLT (另存為 .xsl,一個特殊的 .xml 檔案)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/StudyFieldsResponse">
<xsl:copy>
<xsl:apply-templates select="descendant::FieldValues[@Field='code']/FieldValue"/>
</xsl:copy>
</xsl:template>
<xsl:template match="FieldValues[@Field='code']/FieldValue">
<xsl:variable name="curr_code"><xsl:value-of select="text()"/></xsl:variable>
<xsl:for-each select="ancestor::StudyFields/FieldValues[@Field='Gender']/FieldValue">
<xsl:copy>
<id><xsl:value-of select="ancestor::StudyFields/FieldValues[@Field='id']/FieldValue"/></id>
<gender><xsl:copy-of select="text()"/></gender>
<code><xsl:copy-of select="$curr_code"/></code>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Online Demo
R
library(XML)
# TRANSFORM INPUT TO FLATTER OUTPUT AND SAVE TO DISK
system("xsltproc style.xsl input.xml -o output.xml")
doc <- xmlParse("output.xml")
# BIND TO DATA FRAME
field_values_df <- xmlToDataFrame(doc)
field_values_df
# id gender code
# 1 327635 Male 55905
# 2 327635 Female 55905
# 3 555828 Male 55407-1139
# 4 555828 Male 77030
# 5 555828 Male 90901
# 6 555828 Male 23144
如果您使用 Windows,請考慮使用 PowerShell 腳本
PowerShell (另存為 .ps1)
param ($xml, $xsl, $output)
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform
$xslt.Load($xsl)
$xslt.Transform($xml, $output)
R
library(XML)
# TRANSFORM INPUT TO FLATTER OUTPUT AND SAVE TO DISK
system("PowerShell -ExecutionPolicy bypass -File transform.ps1 input.xml style.xsl output.xml")
doc <- xmlParse("output.xml")
# BIND TO DATA FRAME
field_values_df <- xmlToDataFrame(doc)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/508606.html