2009-04-22 1 views
4

Ich muss beliebige (syntaktisch gültige) XML-Dokumente in ein Wrapper-XML-Dokument einbetten. Die eingebetteten Dokumente sind als reiner Text zu betrachten, sie müssen nicht analysiert werden können, wenn das Wrapper-Dokument analysiert wird.Einbinden von beliebigem XML in XML

weiß, dass ich über die „CDATA trick“, aber das kann ich nicht verwenden, wenn das innere XML-Dokument selbst enthält ein CDATA Segment, und ich muß in der Lage sein jedes gültiges XML-Dokument einbetten. Jeder Ratschlag, um dies zu erreichen - oder die CDATA-Beschränkung zu umgehen - wäre willkommen.

+0

Ihren Kommentar zu meiner Antwort Lesen, scheint es, als würden wir über zwei verschiedene Dinge zu reden. Ich sprach über die Kapselung von XML-Text in einem XML-Dokument: zum Beispiel das Einfügen eines Beispielprogramms in einen Beitrag. Sie scheinen damit zu reden, einfach wohlgeformtes XML mit wohlgeformterem XML zu umhüllen. In diesem Fall ist eine Textverkettung die beste Wahl (obwohl beide Textteile von einem Serializer erzeugt werden sollten). – kdgregory

+0

Beachten Sie, dass ein solches Wrapping keine CDATA beinhaltet ... – kdgregory

+0

Das wohlgeformte XML, das ich umbrechen muss, ist selbst ein wohlgeformtes XML-Dokument, das dann in ein XML-Dokument eingebettet werden muss (und anschließend extrahierbar sein kann). Deine Antwort und meine Epiphanie haben das Problem sauber gelöst. –

Antwort

3

Sie müssen den Text richtig entkommen lassen. Sie sagen nicht, welche Sprache Sie verwenden, aber generell: Sie erstellen ein DOM, erstellen einen Textknoten, der Ihr "inneres" XML enthält, und serialisieren dann dieses DOM. Der Serializer wird für Sie entgehen.

Der Schlüsselpunkt hier ist Verwenden Sie einen Serializer, um Ihre Ausgabe zu produzieren. Schreiben Sie nicht einfach Strings, weil Sie garantiert nur etwas produzieren, das nicht wohlgeformtes XML ist.

+0

Zweimal fing ich an zu kommentieren, während diese Antwort gut war, passte es nicht zu dem, was ich tat, was viel vereinfachterweise einen Text-Stream empfing, der ein XML-Dokument enthielt, das in XML verpackt und zurückgesendet werden musste. Das Parsen zu einem DOM war nicht Teil der Aufgabe. Aber ich habe meine Kommentare abgebrochen.Diese Antwort belastete mich nur und ich hatte endlich eine Offenbarung: Während die Eingabe zeitkritisch war, war die Ausgabe nicht. Drehe also einen Thread, um den XML-Code zu puffern, zu parsen, zu umbrechen und zu serialisieren. Erledigt! –

2

Wenn Sie die endende eckige Klammer des inneren CDATA umgehen, beschweren sich die meisten XML-Parser nicht über die Wohlgeformtheit Ihres XML. Mit dieser "Problemumgehung" sollten Sie in der Lage sein, mehrere CDATA-Abschnitte zu verschachteln.

Etwas wie:

<?xml version="1.0"?> 
<SomeData> 
<![CDATA[ 
<SomeMoreData> 
<![CDATA[ 
yeah, this trick rocks! ... 
]]&gt; 
</SomeMoreData> 
]]> 
</SomeData> 

Beachten Sie, dass die innere CDATA seine Endung hat ">" entkam als &gt;.

1

Verwenden Sie XInclude, anstatt zu versuchen, ein XML-Dokument in ein anderes einzubetten. Das XInclude-Attribut parse = "text" erzwingt, dass die XML-Datei als Text und nicht als Markup behandelt wird.

1

Eine einfache Lösung ist, dass Sie benachbarte CDATA-Abschnitte haben können. <![CDATA[A]]><![CDATA[B]]> ist das gleiche wie <![CDATA[AB]]>. Daher können Sie <![CDATA[]]]]><![CDATA[>]]>, ein ]]> Close Tag über zwei CDATA Abschnitte aufgeteilt haben.

4

Sie können dies tun, indem Sie einfach das Dokument (ohne seineDeklaration) als Kind ein Elternteil hinzufügen. SOAP tut dies - es hat ein <Body> Element, das jede XML-Nachricht enthalten kann, die man senden möchte.

SOAP XSD auf diese Weise definiert:

<xs:element name="Body" type="tns:Body" /> 
    <xs:complexType name="Body"> 
    <xs:sequence> 
     <xs:any namespace="##any" minOccurs="0" 
      maxOccurs="unbounded" processContents="lax" /> 
    </xs:sequence> 
    <xs:anyAttribute namespace="##any" processContents="lax"> 
    </xs:anyAttribute> 
    </xs:complexType>