1

たとえば、Rにxmlをロードした場合:

library(XML)
top <- newXMLNode("top")
tvp <- newXMLNode("TVP", parent = top)
time <- newXMLNode("time", "2012-01-01", parent = tvp)
value <- newXMLNode("value", "123", parent = tvp)
comment <- newXMLNode("comment",parent = tvp)
qualifer <-newXMLNode("qualifier", attrs = c(y = 'abc'), parent = comment)
commentText <-newXMLNode("info", attrs = c(y = 'something'), parent = comment)
tvp <- newXMLNode("TVP", parent = top)
time <- newXMLNode("time", "2012-01-02", parent = tvp)
value <- newXMLNode("value", "456", parent = tvp)
tvp <- newXMLNode("TVP", parent = top)
time <- newXMLNode("time", "2012-01-03", parent = tvp)
value <- newXMLNode("value", "789", parent = tvp)
comment <- newXMLNode("comment",parent = tvp)
newXMLNode("qualifier", attrs = c(y = 'efg'), parent = comment)
top

結果の XML:

<top>
  <TVP>
    <time>2012-01-01</time>
    <value>123</value>
    <comment>
      <qualifier y="abc"/>
      <info y="something"/>
    </comment>
  </TVP>
  <TVP>
    <time>2012-01-02</time>
    <value>456</value>
  </TVP>
  <TVP>
    <time>2012-01-03</time>
    <value>789</value>
    <comment>
      <qualifier y="efg"/>
    </comment>
  </TVP>
</top> 

修飾子と情報属性を適切に (つまり、適切な場所に) 含むデータフレームを取得するにはどうすればよいですか?

これはほとんど機能しますが、正確には機能しません:

DF <- xmlToDataFrame(top,stringsAsFactors=FALSE)

結果は次のようになります。

        time value comment
1 2012-01-01   123        
2 2012-01-02   456    <NA>
3 2012-01-03   789   

どうすれば入手することができますか:

私が本当に必要としているのは、コメントの子ノードの属性を取得する方法です。

        time value qualifer      info
1 2012-01-01   123      abc something
2 2012-01-02   456                   
3 2012-01-03   789      efg   
4

2 に答える 2

1

以下を試してください。各 TVP について、.//*[not(*)]xpath 式を使用してすべての子孫の葉を見つけます。ここ.で、現在のポイント、つまり現在の TVP ノードで開始することを//*意味し、すべての子孫をトラバースしますが[not(*)]、子を持たないものだけに制限します。次に、TVP ごとに 1 つのリスト コンポーネントの値 (値がない場合は属性) のリストを作成します。最後の行では、各リスト コンポーネントを行列に変換し、plyr を使用しrbind.fill.matrixて行列をまとめます。

xp <- xpathApply(top, "/top/TVP", xpathSApply, ".//*[not(*)]", function(x)
       setNames(ifelse(nzchar(xmlValue(x)), xmlValue(x), xmlAttrs(x)), xmlName(x)))
library(plyr)
do.call(rbind.fill.matrix, lapply(xp, t))

ちなみに、私の Windows GUI システム (RStudio なし) では、コメントのコードもクラッシュしました。

更新: ソリューションのマイナーな短縮

于 2013-08-30T19:41:53.847 に答える
1

次のコードを試してください。

require(plyr) ### provides rbind.fill
getDataframe <- function(xml){
 out2 <- xmlSApply(xml,function(x){
 out <- xmlSApply(x, function(y){
  if(length(xmlChildren(y)) > 1){xmlSApply(y,xmlAttrs)
   }else{xmlValue(y)}})
  as.data.frame(t(unlist(out))) ## rbind.fill likes dataframes
  })
  return(do.call(rbind.fill,out2))
}
getDataframe(top)

ここでの考え方は次のとおりです。

  • xml コンポーネントに子があるかどうかを確認します。次にxmlAttrsを使用します
  • xmlValue を使用する子がない場合
  • これでリストが得られますが、data.frame が必要です
  • 一部の値が欠落しているため、plyr パッケージの rbind.fill が必要です。
  • 最後に、rbind.fill を満足させるために、スマートな変換 (as.data.frame) が必要です。
于 2013-08-30T19:04:29.803 に答える