2011-08-04 12 views
7

Editar: Mi traducción de cabeceras XmlLite (incompleta y muy áspero) está disponible en GitHubCómo combinar grandes archivos XML utilizando MSXML SAX en Delphi

¿Cuál es la mejor manera de hacer una simple combinan de documentos masivos XML en Delphi con MSXML sin usar DOM? ¿Debo usar los componentes COM SAXReader y XMLWriter y hay buenos ejemplos?

La transformación es una combinación simple de todos los elementos de contenido de la raíz (Contenedor) de muchos archivos grandes (60 MB +) a un archivo enorme (~ 1 GB).

<Container> 
    <Contents /> 
    <Contents /> 
    <Contents /> 
</Container> 

tengo que trabajar en el siguiente código C# utilizando un XmlWriter y XmlReaders, pero tiene que ocurrir en un proceso Delphi nativo:

var files = new string[] { @"c:\bigFile1.xml", @"c:\bigFile2.xml", @"c:\bigFile3.xml", @"c:\bigFile4.xml", @"c:\bigFile5.xml", @"c:\bigFile6.xml" }; 

using (var writer = XmlWriter.Create(@"c:\HugeOutput.xml", new XmlWriterSettings{ Indent = true })) 
{ 
    writer.WriteStartElement("Container"); 

    foreach (var inputFile in files) 
     using (var reader = XmlReader.Create(inputFile)) 
     { 
      reader.MoveToContent(); 
      while (reader.Read()) 
       if (reader.IsStartElement("Contents")) 
        writer.WriteNode(reader, true); 
     } 

    writer.WriteEndElement(); //End the Container element 
} 

Ya utilizamos MSXML DOM en otras partes del sistema y no quiero agregar nuevos componentes si es posible.

+1

Así que desea utilizar SAX para evitar el consumo de unos pocos gigas de RAM? ¿Ayuda esta demostración SAX-with-MSXML? http://keith-wood.name/DelphiXML/BookCode/Chapter%2013/index.html –

+0

Sí, Delphi compila solo 32 bits y el envoltorio TXMLDocument basado en DOM para MSXML se bloquea con EOutOfMemory cuando los documentos alcanzan ~ 100MB. – carlmon

+0

Mi opinión es soltar MSXML por completo, y vaya con OmniXML. :-) Debería poder cargar un archivo XML de 1 gig en un proceso de 32 bits, en cualquier motor XML diseñado de forma sana. –

Respuesta

3

XmlLite es un nativo de C++ puerto de lector y escritor xml de System.XML, que proporciona el tirón de análisis modelo de programación. Está en la caja con W2K3 SP2, WinXP SP3 y superior. Necesitará una traducción del encabezado Delphi antes de la asignación de casi 1-1 de C# a Delphi.

+1

Delphi/Object Pascal framework de persistencia tiOPF (http://wiki.freepascal.org/tiOPF) apoya XmlLite así que supongo que este proyecto de código abierto ya incluye las traducciones de cabecera – mjn

+0

Gracias Samuel, MS XmlLite funciona bien! tiOPF parece tener algo más llamado XmlLite (o no pude encontrar la unidad), así que escribí mi propia traducción de encabezado para los bits que necesitaba. – carlmon

+1

@carlmon: ¿quizás podrías compartir tu traducción de encabezado? – jpfollenius

1

Solo utilizaría la E/S de archivo común para escribir en un archivo de texto, escribir cada uno de los contenidos como una cadena, y finalmente escribir. Si tuviera un tamaño más razonable, ensamblaría todo en una lista de cadenas y luego lo transmitiría al disco. Pero si estás en el territorio de GB, eso sería arriesgado.

+1

Sin duda, la cosa delphi SAX-with-MSXML es funcional. –

+0

Puedo recurrir a esto, pero olvidé mencionar un elemento de encabezado de tamaño variable en los archivos que deben ignorarse para el resultado. Hace que los archivos directos se vuelvan un poco hacky ... – carlmon

+1

Recurrir a esto en lugar de usar un analizador de SAX probado sería tonto. (? No voy a utilizar los nuevos componentes, a menos que me los invento a partir de cero) –

1

libxml con la envoltura Delphi Libxml2 podría ser una opción (que se encuentra here), que tiene algo de apoyo SAX y parece ser muy sólida - la página web menciona que libxml2 pasó todas las pruebas de 1800 + de la suite de pruebas OASIS XML. Consulte también: Is there a SAX Parser for Delphi and Free Pascal?

+0

escribí mi propio envoltorio LibXML para Delphi 5 hace unos años, pero estandarizadas en MSXML más reciente en Delphi para evitar la hinchazón y dependencias - nos vinculen o envío de 3 motores XML diferentes en una etapa o_O. – carlmon

+0

Así que ahora tiene 1 y es el más buggiest y es parte del sistema operativo en lugar de enviar una buena versión conocida con su aplicación. :-) –

0

Publicando esto como respuesta porque necesita espacio y formato.

Tengo un archivo de datos para las pruebas baaad ver el mensaje en https://github.com/the-Arioch/omnixml/commit/d1a544048e86921983fced67c772944f12cb1427

Aquí OmniXML tipo de chupa en XE2 depuración de construcción:

  • Alrededor de un 25% más que el uso de la memoria TXMLDocument/MSXML. Tal vez incluso más después de solucionar el problema .NextSibling, no volvió a probar.
  • duración de la carga más largo (otoh significativamente más rápidas propiedades del nodo de lectura: son variables ya mecanografiadas-Delphi, sin cruce de MSXML/Delphi límite)
  • absolutamente ningún soporte para espacios de nombres, lo que hace que las etiquetas que reconocen la forma más difícil
  • XPath en estado embrionario, incluyendo una vez más la falta de espacios de nombres

https://docs.google.com/spreadsheets/d/1QcFVwh3fFfaDyRmv2b-n4Rq4_u5p42UfNbR_FZgZizY/edit?usp=sharing

Cuestiones relacionadas