36 Stimmen

Ist es möglich, HTML-Text oder CDATA innerhalb eines XML-Attributs zu haben?

Ich erhalte ständig "XML-Parser-Fehler: Unterminiertes Attribut" mit meinem Parser, wenn ich versuche, HTML-Text oder CDATA innerhalb meines XML-Attributs einzufügen. Gibt es eine Möglichkeit, dies zu tun, oder ist dies nach dem Standard nicht zulässig?

31voto

JMP Punkte 7533

Nein, Die Markierung, die eine CDATA-Abschnitt ist als Wert eines Attributs nicht zulässig.

Nach der Spezifikation ist dieses Verbot eher indirekt als direkt. Die Spezifikation besagt, dass der Attributwert darf keine offene eckige Klammer haben . Offene eckige Klammern und kaufmännische Und-Zeichen müssen ausgeschnitten werden. Daher können Sie keinen CDATA-Abschnitt einfügen. womp womp.

Ein CData-Abschnitt wird nur interpretiert, wenn er sich in einem Textknoten eines Elements befindet.

16voto

John Kugelman Punkte 327535

Attribute können nur einfachen Text enthalten, keine Tags, Kommentare oder andere strukturierte Daten. Sie müssen alle Sonderzeichen durch die Verwendung von Zeicheneinheiten ausschließen. Zum Beispiel:

<code text="&lt;a href=&quot;/&quot;&gt;">

Damit würde die text Attribut den Wert <a href="http://stackoverflow.com/"> . Beachten Sie, dass es sich hierbei nur um reinen Text handelt. Wenn Sie ihn also als HTML behandeln wollten, müssten Sie die Zeichenfolge selbst durch einen HTML-Parser laufen lassen. Das XML-DOM würde den String nicht analysieren. text Attribut für Sie.

12voto

n611x007 Punkte 8422

CDATA ist hier leider eine zweideutige Aussage. Es gibt "CDATA-Abschnitte" et " CDATA Attribut Typ" .

Ihr Attributwert kann vom Typ CDATA mit dem "CDATA-Attribut-Typ" sein.

Hier ist eine xml-Datei, die eine "CDATA-Abschnitt" ( alias. CDSect ):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<elemke>
<![CDATA[
foo
]]>
</elemke>

Hier ist eine xml-Datei, die eine "CDATA-Attribut Typ" (als AttType ):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE elemke [
<!ATTLIST brush wood CDATA #REQUIRED>
]>

<elemke>
<brush wood="guy&#xA;threep"/>
</elemke>

Sie kann nicht verwenden eine "CDATA-Abschnitt" für ein Attribut Wert: falsch: <brush wood=<![CDATA[foo]]>/>

Sie kann verwenden eine "CDATA-Attribut Typ" für den Typ Ihres Attributs, denke ich, dass dies im Normalfall tatsächlich geschieht, und Ihr Attributwert es eigentlich ein CDATA: für ein Element wie <brush wood="guy&#xA;threep"/> in dem rohen binären Bytestring, der die .xml Datei, haben Sie guy&#xA;threep Wenn die Datei jedoch verarbeitet wird, wird der Attributwert im Speicher wird sein

guy
threep

Ihr Problem könnte darin liegen, 1) eine richtige Xml-Datei zu erzeugen und 2) einen "Xml-Prozessor" so zu konfigurieren, dass er die gewünschte Ausgabe erzeugt.

Zum Beispiel, für den Fall, dass Sie von Hand eine rohe Binärdatei als Xml-Datei schreiben müssen Sie diese Escapes in den Attributwertteil in der Rohdatei einfügen, wie ich es geschrieben habe <brush wood="guy&#xA;threep"/> hier, anstelle von <brush wood="guy (Zeilenumbruch) threep"/>

Dann das Parsen würde tatsächlich einen Zeilenumbruch ergeben, ich habe das mit einem Prozessor ausprobiert.

Sie können es mit einem Prozessor wie Saxon probieren oder als Arme-Leute-Experiment mit einem Browser, indem Sie die xml-Datei in Firefox öffnen und Kopieren des Wertes in einen Texteditor - firefox angezeigt den Zeilenumbruch als Leerzeichen, aber beim Kopieren der Zeichenkette in einen Texteditor wurde der Zeilenumbruch angezeigt. (Mit einem besser geeigneten Prozessor könnten Sie die direkte Ausgabe wahrscheinlich sofort speichern).

Jetzt müssen Sie "nur" noch dafür sorgen, dass Sie dieses CDATA angemessen behandeln. Wenn Sie z. B. ein XSL-Stylesheet haben, das eine HTML-Datei erzeugt, können Sie etwas wie Folgendes verwenden .xsl für ein solches xml:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="split">
  <xsl:param name="list"      select="''" />
  <xsl:param name="separator" select="'&#xA;'" />
  <xsl:if test="not($list = '' or $separator = '')">
    <xsl:variable name="head" select="substring-before(concat($list, $separator), $separator)" />
    <xsl:variable name="tail" select="substring-after($list, $separator)" />

    <xsl:value-of select="$head"/>
    <br/><xsl:text>&#xA;</xsl:text>
    <xsl:call-template name="split">
        <xsl:with-param name="list"      select="$tail" />
        <xsl:with-param name="separator" select="$separator" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

<xsl:template match="brush">
  <html>
  <xsl:call-template name="split">
    <xsl:with-param name="list" select="@wood"/>
  </xsl:call-template>
  </html>
</xsl:template>

</xsl:stylesheet>

Die in einem Browser oder mit einem Prozessor wie saxon mit java -jar saxon9he.jar -s:eg2.xml -xsl:eg2.xsl -o:eg2.html saxon home edition 9.5 würde dieses html-ähnliche Ding erzeugen:

<html>guy<br>
   threep<br>

</html>  

die in einem Browser wie folgt aussehen wird:

guy
threep

Hier verwende ich eine rekursive Vorlage 'split'. von Tomalak Dank an Mads Hansen weil mein Zielprozessor beides nicht unterstützt string-join noch tokenize die nur der Version 2.0 entsprechen.

10voto

Rich Seller Punkte 81404

Handelt es sich bei einem Attribut nicht um einen tokenisierten oder enumerierten Typ, wird es als CDATA verarbeitet. Die Einzelheiten zur Verarbeitung des Attributs finden Sie in der Extensible Markup Language (XML) 1.0 (Fünfte Ausgabe) .

3.3.1 Attributstypen

Es gibt drei Arten von XML-Attributtypen: einen Stringtyp, eine Reihe von tokenisierten Typen und aufgezählte Typen. Der Stringtyp kann eine beliebige Zeichenkette als Wert annehmen; die tokenisierten Typen sind stärker eingeschränkt. Die in der Grammatik vermerkten Gültigkeitseinschränkungen werden angewendet, nachdem der Attributwert normalisiert wurde, wie in 3.3.3 Normalisierung von Attributwerten beschrieben.

[54]  AttType       ::=    StringType | TokenizedType | EnumeratedType
[55]  StringType    ::=    'CDATA'
[56]  TokenizedType ::=    'ID' [VC: ID]
            [VC: One ID per Element Type]
            [VC: ID Attribute Default]
        | 'IDREF'      [VC: IDREF]
        | 'IDREFS'     [VC: IDREF]
        | 'ENTITY'     [VC: Entity Name]
        | 'ENTITIES'   [VC: Entity Name]
        | 'NMTOKEN'    [VC: Name Token]
        | 'NMTOKENS'   [VC: Name Token]

...

3.3.3 Normalisierung von Attribut-Werten

Bevor der Wert eines Attributs an die Anwendung weitergegeben oder auf Gültigkeit geprüft wird, MUSS der XML-Prozessor den Attributwert normalisieren, indem er den nachstehenden Algorithmus anwendet oder eine andere Methode einsetzt, so dass der an die Anwendung weitergegebene Wert mit dem durch den Algorithmus erzeugten Wert identisch ist.

  1. Alle Zeilenumbrüche MÜSSEN bei der Eingabe in #xA normalisiert worden sein, wie in 2.11 End-of-Line-Behandlung Der Rest des Algorithmus arbeitet also mit auf diese Weise normalisiertem Text.
  2. Beginnen Sie mit einem normalisierten Wert, der aus einer leeren Zeichenkette besteht.
  3. Führen Sie für jedes Zeichen, jede Entitätsreferenz oder jede Zeichenreferenz im nicht normalisierten Attributwert, beginnend mit dem ersten und fortfahrend bis zum letzten, Folgendes aus:
    • Bei einer Zeichenreferenz wird das referenzierte Zeichen an den normalisierten Wert angehängt.
    • Für eine Entitätsreferenz wenden Sie Schritt 3 dieses Algorithmus rekursiv auf den Ersatztext der Entität an.
    • Für ein Leerzeichen (#x20, #xD, #xA, #x9) wird ein Leerzeichen (#x20) an den normalisierten Wert angehängt.
    • Bei einem anderen Zeichen wird das Zeichen an den normalisierten Wert angehängt.

Wenn der Attributtyp nicht CDATA ist, MUSS der XML-Prozessor den normalisierten Attributwert weiterverarbeiten, indem er alle führenden und nachfolgenden Leerzeichen (#x20) verwirft und Folgen von Leerzeichen (#x20) durch ein einzelnes Leerzeichen (#x20) ersetzt.

Enthält der nicht normalisierte Attributwert einen Zeichenverweis auf ein Leerzeichen, das kein Leerzeichen ist (#x20), enthält der normalisierte Wert das referenzierte Zeichen selbst (#xD, #xA oder #x9). Dies steht im Gegensatz zu dem Fall, in dem der nicht normalisierte Wert ein Leerzeichen (keine Referenz) enthält, das im normalisierten Wert durch ein Leerzeichen (#x20) ersetzt wird, und steht auch im Gegensatz zu dem Fall, in dem der nicht normalisierte Wert eine Entitätsreferenz enthält, deren Ersetzungstext ein Leerzeichen enthält; da dieser rekursiv verarbeitet wird, wird das Leerzeichen im normalisierten Wert durch ein Leerzeichen (#x20) ersetzt.

Alle Attribute, für die keine Deklaration gelesen wurde, SOLLTEN von einem nicht-validierenden Prozessor so behandelt werden, als ob sie deklariert wären CDATA .

Es ist ein Fehler, wenn ein Attributwert enthält eine Referenz zu einer Entität, für die keine Erklärung gelesen wurde.

2voto

sumit raju Punkte 21

Wir können CDATA nicht als Attribut verwenden, aber wir können HTML mit HTML-Codes binden. Hier ist ein Beispiel:

um dies zu erreichen: <span class="abc"></span>

XML-Code wie diesen verwenden:

<xmlNode attibuteName="&lt;span class=&quot;abc&quot;&gt;Your Text&lt;&#47;span&gt;"></xmlNode>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X