2016-07-26 7 views
1

Ich habe 2 Dateien vom Typ:Wie vergleichen Sie zwei XML-Dateien in mssql

@xmlAuthors1 XML =N' 
     <Author name="John" surname="Clinton" /> 
     <Author name="Bill" surname="Skobov" /> 
     <Author name="John" surname="Lokwood" />; 

@xmlAuthors2 XML =N' 
     <Author name="Bill" surname="Skobov" /> 
     <Author name="John" surname="Clinton" /> 
     <Author name="John" surname="Lokwood" />; 

wie finden heraus, dass sie gleich sind? Vergleichen Sie jede Zeile der Datei 1 mit jeder Zeile aus der Datei 2

+1

Siehe http://stackoverflow.com/questions/9013680/t-sql-how-can-i-compare-two-variables-of-type-xml-when-length-varcharmax – Serg

Antwort

3

Zum Beispiel Sie sie mögen vergleichen kann:

DECLARE @xmlAuthors1 XML = N' 
       <Author name="John" surname="Clinton" /> 
       <Author name="Bill" surname="Skobov" /> 
       <Author name="John" surname="Lokwood" />', 
     @xmlAuthors2 XML =N' 
       <Author name="Bill" surname="Skobov" /> 
       <Author name="Johns" surname="Clinton" /> 
       <Author name="John" surname="Lokwood" />' 


SELECT * 
FROM (
    SELECT CAST(x1.t.query('.') as nvarchar(max)) as x1, 
      CAST(x2.t.query('.') as nvarchar(max)) as x2 
    FROM @xmlAuthors1.nodes('/*') as x1(t) 
    FULL OUTER JOIN @xmlAuthors2.nodes('/*') as x2(t) 
     ON CAST(x1.t.query('.') as nvarchar(max)) = CAST(x2.t.query('.') as nvarchar(max)) 
) as x 
WHERE x1 is null or x2 is null 

Wenn gleich es

+0

Haben Sie dies testen mit Daten ungleich? – Shnugo

+1

Guck mal genauer hin ... Deine Idee kommt mir sehr nahe, du wirfst das ganze Element als String ... Aber das 'WHERE x1! = X2' behandelt nicht die' NULL's, die die fehlenden Werte anzeigen aus dem 'FULL OUTER JOIN' ... – Shnugo

+0

Ja, ich habe getestet, funktioniert gut, wenn x1 einen Wert hat und x2 null ist oder x1 null ist und x2 mit einem Wert. – gofr1

1

Es hängt nicht ausgegeben werden, was Gleich bedeutet für dich. Ich würde Daten vergleichen, wie folgt:

DECLARE @xmlAuthors1 XML =N' 
     <Author name="John" surname="Clinton" /> 
     <Author name="Bill" surname="Skobov" /> 
     <Author name="John" surname="Lokwood" /> 
     <Author name="John" surname="Blurred" />'; 

DECLARE @xmlAuthors2 XML =N' 
     <Author name="Bill" surname="Skobov" /> 
     <Author name="John" surname="Clinton" /> 
     <Author name="John" surname="Lokwood" />'; 

WITH Xml1 AS 
(
    SELECT 
     T.A.value('@name', 'varchar(20)') Name, 
     T.A.value('@surname', 'varchar(20)') Surname 
    FROM @xmlAuthors1.nodes('/Author') T(A) 
), Xml2 AS 
(
    SELECT 
     T.A.value('@name', 'varchar(20)') Name, 
     T.A.value('@surname', 'varchar(20)') Surname 
    FROM @xmlAuthors2.nodes('/Author') T(A) 
) 
SELECT 'Unique in 1' [Description], * FROM (SELECT * FROM Xml1 EXCEPT SELECT * FROM Xml2) Q1 
UNION ALL 
SELECT 'Unique in 2' [Description], * FROM (SELECT * FROM Xml2 EXCEPT SELECT * FROM Xml1) Q2 

diesem speziellen Beispiel ergibt:

Description Name Surname 
----------- ---- ------- 
Unique in 1 John Blurred 
1

Das war mein Ansatz:

Es gibt einen schönen Trick mit .query(.data()).value() alle inneren Text als Raum zurückzuholen getrennt Zeichenfolge. Dies macht es einfach auf String-Ebene vergleichen ...

Ich änderte Ihre Eingabe noch einige Testfälle inlcude:

DECLARE @xmlAuthors1 XML = N' 
       <Author name="John" surname="Clinton" /> 
       <Author name="Bill" surname="Different" /> 
       <Author name="John" surname="Lokwood" /> 
       <Author name="Test" surname="it" />', 
     @xmlAuthors2 XML =N' 
       <Author name="Bill" surname="Skobov" /> 
       <Author name="John" surname="Clinton" /> 
       <Author name="John" surname="Lokwood" /> 
       <Author name="One" surname="More" />'; 

SELECT ISNULL(Author1,Author2) AS Author 
     ,CASE WHEN Author1 IS NULL THEN 'Exists in 2' ELSE 'Exists in 1' END AS [Source] 
FROM 
(
    SELECT B.query('data(@*)').value('.','varchar(max)') AS Author1 
    FROM @xmlAuthors1.nodes('/Author') AS A(B) 
) AS tbl1 
FULL OUTER JOIN 
( 
    SELECT B.query('data(@*)').value('.','varchar(max)') As Author2 
    FROM @xmlAuthors2.nodes('/Author') AS A(B) 
)AS tbl2 ON Author1=Author2 
WHERE Author1 IS NULL OR Author2 IS NULL 

Wenn Sie möchten, diejenigen finden, die in beide gleich sind, könnten Sie diese

verwenden
SELECT B.query('data(@*)').value('.','varchar(max)') AS EqualAuthor 
FROM @xmlAuthors1.nodes('/Author') AS A(B) 
INTERSECT 
SELECT B.query('data(@*)').value('.','varchar(max)') 
FROM @xmlAuthors2.nodes('/Author') AS A(B)