2010-03-03 49 views
9

Necesito incrustar un documento xml bien formado dentro de otro documento xml. Sin embargo, prefiero evitar CDATA (disgusto personal) y también me gustaría evitar que el analizador sintáctico que recibirá todo el documento pierda tiempo analizando el xml incrustado. El xml incrustado podría ser bastante significativo, y me gustaría que el código que recibirá el archivo completo trate el xml incrustado como datos arbitrarios.Cómo incrustar xml en xml

La idea que inmediatamente se me ocurrió es codificar el xml incrustado en base64 o comprimirlo. ¿Suena bien?

Estoy programando en C# por cierto.

+2

Esto no se trata de software integrado y realmente no debería etiquetarse como tal. –

Respuesta

3

Solo una nota rápida, he seguido la ruta de base64 y funciona bien, pero tiene una penalización de rendimiento rígida, especialmente cuando se usa mucho. Hacemos esto con fragmentos de documentos de hasta 20 MB y después de la codificación base64 pueden tomar más de 65 MB (con etiquetas y datos), incluso con compresión.

Sin embargo, el problema más grande es que la codificación .NET base64 puede consumir hasta 10 veces la memoria al realizar la codificación/decodificación y con frecuencia puede causar excepciones OOM si se realiza de forma repetida y/o en múltiples subprocesos.

Alguien, en una pregunta similar, recomendó ProtoBuf como una opción, así como Fast InfoSet como otra opción.

+0

Dado que los datos que deseo incorporar son XML, es altamente compresible, después de algunas pruebas parece que si primero comprime el xml antes de convertirlo a base64, el tamaño resultante en bytes es aproximadamente un 10% menor que la cantidad de datos recogidos por el xml precompresión sin procesar. ¡Creo que tomaré esta ruta! – tempy

+0

Creo que es posible que desee probar el puerto C# de vtd-xml, muchos de los problemas con DOM se resuelven muy bien, como el rendimiento (parece preocuparse por el análisis) y el uso de memoria, pero es un conjunto de herramientas externo (no parte de la distribución .NET) http://vtd-xml.sf.net –

+0

Gracias por el enlace @Jimmy zhang – GrayWizardx

1

Lo codificaría de la manera que prefiera (por ejemplo, base64 o HttpServerUtility :: UrlEncode, ...) y luego lo incrustaré.

5

Puede convertir el XML a una matriz de bytes, y luego convertirlo a formato binary64. Eso le permitirá anidarlo en un elemento y no tener que usar CDATA.

4

La manera aprobada por el W3C de hacer esto es XInclude. Hay una implementación para .Net en http://mvp-xml.sourceforge.net/xinclude/

+2

El.NET Framework no tiene una implementación XInclude. –

+1

El enlace que publiqué es una implementación de XInclude para .Net en C#. –

3

Dependiendo de cómo construya el XML, una forma es no preocuparse por ello y dejar que el marco lo maneje.

XmlDocument doc = new XmlDocument(); 
doc.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?><helloworld></helloworld>"); 
string xml = "<how><are><you reply=\"i am fine\">really</you></are></how>"; 
doc.GetElementsByTagName("helloworld")[0].InnerText = xml; 

La salida será algo así como una cadena HTMLEncoded:

<?xml version="1.0" encoding="utf-8"?> 
<helloworld>&lt;how&gt;&lt;are&gt;&lt;you 
    reply="i am fine"&gt;really&lt;/you&gt;&lt;/are&gt;&lt;/how&gt; 
</helloworld> 
1

Si usted no necesita la declaración XML (primera línea del documento), basta con insertar el elemento raíz (con todos los niño) en el árbol del otro documento xml como hijo de un elemento existente. Use un espacio de nombre diferente para separar los elementos insertados.

+0

Esto todavía resultaría en que el analizador en el extremo receptor analizara el xml incrustado, lo cual me gustaría evitar . – tempy

+1

@tempy el analizador tiene que analizar los datos codificados en CDATA o base 64 también, para comprobar que está bien formado y para pasarlo a la aplicación como datos de caracteres. Tendrás que compararlo para ver si tirar la estructura cuesta más o menos que analizar los bytes adicionales en base64 –

+0

@Pete Kirkham Ese es un buen punto ... Tendré que investigar. – tempy

-1

utilizan los comentarios para esto:

< - el XML de texto - >

[Editado]
Si el código XML incrustado con los comentarios, reemplazarlo con una sintaxis diferente!.

 
<?xml version="1.0" encoding="iso-8859-1" ?> 
<xml> 
    <status code="0" msg="" cause="" /> 
    <data> 
     <order type="07" user="none" attrib="..." > 
     <xmlembeded > 
      <!-- 
       <?xml version="1.0" encoding="iso-8859-1" ?> 
       <xml> 
       <status ret="000 "/> 
       <data> 
       <allxml_here /> 
       <!** embedeb comments **> 
       </data> 
       <xml> 
      --> 
     </xmlembeded > 
     </order> 
     <context sessionid="12345678" scriptname="/from/..." attrib="..." /> 
    </data> 
</xml> 
+1

¿Qué sucede si hay comentarios en el xml incorporado también? ¿No descomentaría el resto? –

+0

Este no es mi caso, sé a qué estoy ingresando. – lsalamon

+0

Esto huele demasiado a hack-ish para mí. Limpiar el xml interno de comentarios, que requeriría tratarlo como una cadena potencialmente gigante, podría ser bastante costoso y creo que podría evitarse usando otros métodos. – tempy

0

¿No puedes usar XSLT para esto? Quizás usando xsl: copy o xsl: copy-of? Esto es para lo que XSLT es.