2012-09-10 1 views
8

Ho recentemente creato una piccola finestra C# Windows/LINQ all'app XML in VS2010 che fa esattamente ciò che deve fare, ad eccezione di una cosa: aggiunge " [] "fino alla fine del tag DOCTYPE, che apparentemente sta causando il rigetto dei file da un sistema legacy. Ecco un prima e dopo:C# LINQ TO XML - Rimuovere i caratteri "[]" dall'intestazione DTD

Prima

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

Dopo

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

Questi caratteri vengono aggiunti dopo che il file viene salvato all'interno del programma usando la funzione .save. Il programma consente la selezione di un file .xml, quindi "pulisce" rimuovendo determinati tag, quindi lo salva. Quando inizia il processo, i file non hanno il "[]" nel DOCTYPE. Dopo aver salvato, lo fanno. LINQ to XML aggiunge questi?

C'è un modo per impedire al programma di aggiungere questi caratteri?

+1

E 'molto improbabile che Linq aggiungerebbe nulla automaticamente. Perché non metti insieme un piccolo esempio del problema e lo metti qui? – Icarus

risposta

11

Evidentemente, quando XDocument analizza un documento XML che contiene una dichiarazione del tipo di documento, un "sottoinsieme" vuoto viene inserito automaticamente se non esiste uno. (Il sottoinsieme interno è la parte circondata da [] nello <!DOCTYPE>).

Il risultato è un XML ben formato. Tuttavia, se il sistema legacy non è in grado di gestirlo, è possibile rimuovere il sottoinsieme interno del DTD impostando la proprietà per XDocumentType.InternalSubsetnull:

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

Grazie! Questo sembra averlo fatto. Finora sta superando ogni test. – ewomack

+3

Nota che al momento non funziona in Mono ('2.10.9'), dato che non puoi assegnare null a' InternalSubset', anche se * puoi * specificare null quando stai creando un nuovo 'XDocumentType'. Quando si analizza/salva un 'Info.plist', questo porta a un catch-22: l'output di' [] 'nel file causerà il fallimento della compilazione in MonoTouch. Il caricamento di 'Info.plist' con un sottoinsieme interno vuoto causa l'emissione di' [] 'e non è possibile impostare' .InternalSubset = null'. E 'XDocument.DocumentType' è di sola lettura. Guai a me! – cod3monk3y

+0

Ho colpito la stessa cosa (usando mono su mac per modificare un Info.plist). Ho trovato una soluzione decente usando XmlDocument per modificare il DOCTYPE dopo aver terminato di lavorare con XDocument, e l'ho postato qui sotto. Fino a quando l'ho trovato, stavo per fare qualche rimpiazzo di stringa orribile o ricorrere a - shudder - XmlReader/XmlWriter. – aggieNick02

7

Se avete a che fare con questo su Mono (come cod3monk3y) per i casi come modificare Info.plist, puoi usare la vecchia classe XmlDocument per sistemare le cose dopo aver usato XDocument per creare/modificare il tuo file xml.

Il codice presuppone il file "Info.plist" si trova al infoPlist percorso:

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);