2009-06-11 12 views
21

Se ho due stringhe di xml1 e xml2 che rappresentano entrambi xml nello stesso formato. Qual è il modo più veloce per combinarli insieme? Il formato non è importante, ma voglio solo sapere come posso sbarazzarmi o?Qual è il modo più veloce per combinare due file xml in uno

xml1:

<?xml version="1.0" encoding="utf-8"?> 
<AllNodes> 
    <NodeA> 
     <NodeB>test1</NodeB> 
     <NodeB>test2</NodeB> 
    </NodeA> 
</AllNodes> 

XM2:

<?xml version="1.0" encoding="utf-8"?> 
<AllNodes> 
    <NodeA> 
     <NodeB>test6</NodeB> 
     <NodeB>test7</NodeB> 
    </NodeA> 
    <NodeA> 
     <NodeB>test99</NodeB> 
     <NodeB>test23</NodeB> 
    </NodeA> 
</AllNodes> 

e avere qualcosa di simile:

<?xml version="1.0" encoding="utf-8"?> 
    <AllNodes> 
      <NodeA> 
       <NodeB>test1</NodeB> 
       <NodeB>test2</NodeB> 
      </NodeA> 
     <NodeA> 
       <NodeB>test6</NodeB> 
       <NodeB>test7</NodeB> 
      </NodeA> 
      <NodeA> 
       <NodeB>test99</NodeB> 
       <NodeB>test23</NodeB> 
      </NodeA> 
    </AllNodes> 
+0

per le mie esigenze, [ho subito scritto qualcosa di fondere (web.config) file XML] (http://pastebin.com/FzkRczZ6). Esiste anche uno [Strumento di fusione file di configurazione] (https://configmerger.codeplex.com/). –

risposta

41

Il modo più semplice per eseguire questa operazione è utilizzare LINQ to XML. È possibile utilizzare Union o Concat in base alle proprie esigenze.

var xml1 = XDocument.Load("file1.xml"); 
var xml2 = XDocument.Load("file2.xml"); 

//Combine and remove duplicates 
var combinedUnique = xml1.Descendants("AllNodes") 
          .Union(xml2.Descendants("AllNodes")); 

//Combine and keep duplicates 
var combinedWithDups = xml1.Descendants("AllNodes") 
          .Concat(xml2.Descendants("AllNodes")); 
+1

bene, il problema è che ho due stringhe anziché due file xml. Queste due string rappresentano elementi xml che vengono inviati da un'altra stazione. C'è un modo per lanciare la mia stringa su XElement o qualcosa del genere? Così posso percorrere i suoi elementi? – paradisonoir

+2

Per convertire la stringa in XElement, è possibile utilizzare XElement.Parse (stringa) –

+2

È possibile convertire la stringa in XDocument anche utilizzando XDocument.Parse (stringa) – Blegger

0

Se fossi facendo questo (utilizzando C#), vorrei creare una classe che posso deserializzare questo XML per (puoi usare xsd.exe per farlo), e poi fare un ciclo attraverso tutti i nodi nell'oggetto che rappresenta il primo pezzo di XML e "Aggiungi" alla proprietà AllNodes dell'oggetto che rappresenta il secondo XML.

Quindi serializzare la seconda classe di nuovo l'XML e dovrebbe essere simile al terzo esempio.

1

Sono disponibili due opzioni di base:

  1. analizzare il codice XML, unire le strutture di dati, serializzare torna a xml.

  2. Se si conosce la struttura, utilizzare alcune manipolazioni di stringa di base per hackerarlo. Ad esempio, nell'esempio sopra puoi prendere l'interno di tutti i nodi nei due blocchi xml e metterli in un unico blocco di allnodes e farlo.

4

una trasformazione XSLT poteva farlo:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:param name="pXml1" select="''" /> 
    <xsl:param name="pXml2" select="''" /> 
    <xsl:param name="pRoot" select="'root'" /> 

    <xsl:template match="/"> 
    <xsl:variable name="vXml1" select="document($pXml1)" /> 
    <xsl:variable name="vXml2" select="document($pXml2)" /> 

    <xsl:element name="{$pRoot}"> 
     <xsl:copy-of select="$vXml1/*/*" /> 
     <xsl:copy-of select="$vXml2/*/*" /> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

Passo nei nomi dei file come parametri, così come il nome del nuovo elemento principale.

Applica a qualsiasi documento XML, ad es. uno vuoto.

+0

Grazie mille. La tua soluzione sembra fantastica, ma sai come posso applicare lo schema a un documento XML? – paradisonoir

+0

Ad esempio, la risposta accettata a http://stackoverflow.com/questions/529374/whats-the-property-way-to-transform-with-xsl-without-html-encoding-my-final-outp mostra come fallo in. NET – Tomalak

+0

D'altra parte, se non hai alcuna conoscenza di XSLT, potrebbe non essere la soluzione ideale per te. E non so come si comporterà rispetto agli altri modi suggeriti in questo thread. – Tomalak

2

Se si può garantire questo formato è possibile combinarli per fare la manipolazione di stringhe:

  • Leggere il primo file, tenere tutto prima di "</AllNodes >"
  • Leggere il secondo file, rimuovere la parte fino a "<AllNodes>"
  • Combina quelle stringhe.

Questo dovrebbe essere il modo più veloce poiché non è necessaria alcuna analisi.

const string RelevantTag = "AllNodes"; 

string xml1 = File.ReadAllText(xmlFile1); 
xml1 = xml1.Substring(0, xml.LastIndexOf("</" + RelevantTag + ">")); 

string xml2 = File.ReadAllText(xmlFile2); 
xml2 = xml2.Substring(xml.IndexOf("<" + RelevantTag + ">") + "<" + RelevantTag + ">".Length, xml1.Length); 

File.WriteAllText(xmlFileCombined, xm1 + xml2); 

Detto questo preferirei sempre la via sicura alla via veloce.

0

Poiché hai chiesto che il più veloce:

Se (e solo se) la struttura XML è sempre coerente: (questo è pseudo codice)

string xml1 = //get xml1 somehow 
string xml2 = //get xml2 somehow 
xml1 = replace(xml1, "<?xml version=\"1.0\" encoding=\"utf-8\"?>", ""); 
xml1 = replace(xml1, "<allnodes>", ""); 
xml1 = replace(xml1, "</allnodes>", ""); 
xml2 = replace(xml2, "<allnodes>", "<allnodes>\n" + xml1); 

Si tratta di un hack gigante ma è veloce. Aspettati di vederlo su TheDailyWTF quando i tuoi colleghi lo troveranno.

1

Se si desidera utilizzare il XmlDocument, provate questo

var lNode = lDoc1.ImportNode(lDoc2.DocumentElement.FirstChild, true); 
lDoc1.DocumentElement.AppendChild(lNode); 
0

var doc = XDocument.Load ("file1.xml");

var doc1 = XDocument.Load ("file2.xml");

doc.Root.Add (doc2.Root.Elements());

4

Questo è il modo più rapido e pulito per unire file xml.

XElement xFileRoot = XElement.Load(file1.xml); 
XElement xFileChild = XElement.Load(file2.xml); 
xFileRoot.Add(xFileChild); 
xFileRoot.Save(file1.xml); 
1

migliore soluzione per me, sulla base di Jose Basilio risposta, leggermente modificata,

var combinedUnique = xml1.Descendants() 
    .Union(xml2.Descendants()); 
combinedUnique.First().Save(#fullName) 
+0

Grazie all'utente @ user3510339 per il codice, tuttavia sta salvando solo il contenuto del primo file XML. TIA – saadasharif

Problemi correlati