2012-09-10 21 views
8

Recientemente creé una aplicación pequeña de formularios de Windows C#/LINQ a XML en VS2010 que hace exactamente lo que se supone que debe hacer, excepto por una cosa: agrega " [] "hasta el final de la etiqueta DOCTYPE, que aparentemente está causando que los archivos sean rechazados desde un sistema heredado. Aquí hay un antes y después:C# LINQ TO XML - Eliminar caracteres "[]" del encabezado DTD

Antes

<!DOCTYPE ichicsr SYSTEM "http://www.accessdata.fda.gov/xml/icsr-xml-v2.1.dtd"> 

Después

<!DOCTYPE ichicsr SYSTEM "http://www.accessdata.fda.gov/xml/icsr-xml-v2.1.dtd"[]> 

Estos caracteres se añaden después de que el archivo se guarda dentro del programa utilizando la función .Save. El programa permite seleccionar un archivo .xml, luego lo "limpia" eliminando ciertas etiquetas y luego lo guarda. Cuando comienza el proceso, los archivos no tienen el "[]" en el DOCTYPE. Después de guardar, lo hacen. ¿LINQ to XML agrega estos?

¿Hay alguna manera de evitar que el programa agregue estos caracteres?

+1

Es muy poco probable que LINQ añadiría nada automáticamente. ¿Por qué no juntas un pequeño ejemplo del problema y lo publicas aquí? – Icarus

Respuesta

11

Evidentemente, cuando XDocument analiza un documento XML que contiene una Declaración de tipo de documento, se inserta automáticamente un "subconjunto interno" vacío si no existe uno. (El subconjunto interno es la parte rodeada por [] en el <!DOCTYPE>).

El resultado es XML bien formado. Sin embargo, si el sistema existente no puede manejar, puede quitar el subconjunto interno del DTD mediante el establecimiento de la propiedad a XDocumentType.InternalSubsetnull:

XDocument document = ...; 
if (document.DocumentType != null) 
    document.DocumentType.InternalSubset = null; 
+0

¡Gracias! Eso parece haberlo hecho. Hasta ahora está pasando todas las pruebas. – ewomack

+3

Tenga en cuenta que esto no funciona actualmente en Mono ('2.10.9'), ya que no puede asignar null a' InternalSubset', aunque * puede * especificar null cuando está creando un nuevo 'XDocumentType'. Al analizar/guardar un 'Info.plist', esto lleva a un catch-22: la salida de' ']' en el archivo hará que la compilación falle en MonoTouch. Cargando 'Info.plist' con un subconjunto interno vacío hace que se emita' [] ', y no puede establecer' .InternalSubset = null'. Y 'XDocument.DocumentType' es de solo lectura. ¡Ay de mí! – cod3monk3y

+0

Pulso lo mismo (usando mono en mac para modificar un Info.plist). Encontré una solución decente usando XmlDocument para modificar el DOCTYPE después de que terminaste de hacer tu trabajo con XDocument, y lo publiqué a continuación. Hasta que lo encontré, estaba a punto de hacer algún reemplazo horrible de cadena o recurrir a - shudder - XmlReader/XmlWriter. – aggieNick02

7

Si se trata de esto en Mono (como cod3monk3y) para los casos como modificar Info.plist, puede usar la antigua clase XmlDocument para arreglar cosas después de usar XDocument para crear/modificar su archivo xml.

El código asume su archivo "Info.plist" se encuentra en la ruta de infoPlist:

using System; 
using System.IO; 
using System.Linq; 
using System.Xml; 
using System.Xml.Linq; 

var xDocument = XDocument.Load (infoPlist); 
// Do your manipulations here 
xDocument.Save (infoPlist); 
XmlDocument xmlDocument = new XmlDocument(); 
xmlDocument.Load (infoPlist); 
if (xmlDocument.DocumentType != null) 
{ 
    var name = xmlDocument.DocumentType.Name; 
    var publicId = xmlDocument.DocumentType.PublicId; 
    var systemId = xmlDocument.DocumentType.SystemId; 
    var parent = xmlDocument.DocumentType.ParentNode; 
    var documentTypeWithNullInternalSubset = xmlDocument.CreateDocumentType(name, publicId, systemId, null); 
    parent.ReplaceChild(documentTypeWithNullInternalSubset, xmlDocument.DocumentType); 
} 
xmlDocument.Save (infoPlist);