2017-11-22 1 views
0

Ich habe zwei komplexe XML-Dateien und ich möchte die Unterschiede zwischen ihnen finden.So finden Sie die Unterschiede zwischen XML-Dateien in R

Was ich brauche, ist zu finden:

  • Tags die
  • Werte in nur einer der beiden XML vorhanden sind, die von einer verschieden sind andere

ich aus der versucht haben compareXMLDocsXML Paket, aber es ist nicht sehr zufriedenstellend.

Beispiel

XML1 
<root> 
    <first>name1</first> 
    <second>id1</second> 
    <third> 
    <third.1>something</third.1> 
    <third.2>something else</third.2> 
    </third> 
    <fifth>no differences</fifth> 
</root> 


XML2 
<root> 
    <second>id2</second> 
    <third> 
    <third.1>something2</third.1> 
    <third.2>something else2</third.2> 
    </third> 
    <fourth>blahblah</fourth> 
    <fifth>no differences</fifth> 
</root> 

Also, wenn ich mit compareXMLDocs vergleichen, ich habe:

> compareXMLDocs(a, b) 
$inA 
first 
    1 

$inB 
fourth 
    1 

$countDiffs 
named integer(0) 

Ich weiß, dass der first Tag nur in XML1 verwendet wird und dass der fourth Tag nur in XML2 verwendet wird . Aber ich weiß nicht, dass die Werte in Terz.1 und Terz.2 unterschiedlich sind. Nach was ich suche. Ich verstehe nicht, was countDiffs tut. Scheint hier nicht sehr nützlich.

Ich habe auch versucht, die XML in Datenrahmen zu konvertieren, aber das Ausgabeformat ist nicht sehr hilfreich. Am schlimmsten wird es bei großen XML-Dateien, bei denen der Baum tief ist.

Das Ergebnis, das ich für dieses Beispiel erwarten würde ein Datenrahmen so aussehen:

Path     A    B 
/root/first   name1   NA 
/root/second   id1    id2 
/root/third/third.1 something  something2 
/root/third/third.2 something else something else2 
/fourth    NA    blahblah 
+0

_ "Tags, die nur in einer der beiden XML vorhanden sind" _ ... nach Knotenposition im Baum? Im Algemeinen? _ "Werte, die sich voneinander unterscheiden" _ ... auf derselben Schlüsselbaumknotenebene in denselben Knoten? – hrbrmstr

Antwort

1

Daten:

library(xml2) 
library(tidyverse) 

read_xml("<root> 
    <first>name1</first> 
    <second>id1</second> 
    <third> 
    <third.1>something</third.1> 
    <third.2>something else</third.2> 
    </third> 
    <fifth>no differences</fifth> 
</root> 
") -> d1 

read_xml(" 
<root> 
    <second>id2</second> 
    <third> 
    <third.1>something2</third.1> 
    <third.2>something else2</third.2> 
    </third> 
    <fourth>blahblah</fourth> 
    <fifth>no differences</fifth> 
</root> 
") -> d2 

Machen Sie eine schnelle Hilfsfunktion:

# NOTE: this will not handle attributes 
as_path_df <- function(x) { 
    as_list(x) %>% 
    unlist() %>% 
    as.list() %>% 
    as_data_frame() %>% 
    gather(key, val) 
} 

Hier was ^^ tut:

(d1_p <- as_path_df(d1)) 
## # A tibble: 5 x 2 
##    key   val 
##   <chr>   <chr> 
## 1   first   name1 
## 2  second   id1 
## 3 third.third.1  something 
## 4 third.third.2 something else 
## 5   fifth no differences 

(d2_p <- as_path_df(d2)) 
## # A tibble: 5 x 2 
##    key    val 
##   <chr>   <chr> 
## 1  second    id2 
## 2 third.third.1  something2 
## 3 third.third.2 something else2 
## 4  fourth  blahblah 
## 5   fifth no differences 

Schlüssel?

setdiff(d1_p$key, d2_p$key) 
## [1] "first" 

Werte? Auch

rename(d1_p, d1_val=val) %>% 
    left_join(rename(d2_p, d2_val=val)) %>% 
    mutate(same = (d1_val == d2_val)) 
## # A tibble: 5 x 4 
##    key   d1_val   d2_val same 
##   <chr>   <chr>   <chr> <lgl> 
## 1   first   name1   <NA>  NA 
## 2  second   id1    id2 FALSE 
## 3 third.third.1  something  something2 FALSE 
## 4 third.third.2 something else something else2 FALSE 
## 5   fifth no differences no differences TRUE 

Sie kann der Lage sein, nur is.na() auf den verschiedenen _val oder same Spalte für den Schlüssel fehlenden Teil, zu verwenden. Aber setdiff() ist super schnell.

Verwandte Themen