2009-01-05 3 views
9

Wie sagt man dem XML-Parser, dass er führende und nachfolgende Leerzeichen berücksichtigt?Können Sie führende und nachfolgende Leerzeichen in XML beibehalten?

Dim xml: Set xml = CreateObject("MSXML2.DOMDocument") 
xml.async = False 
xml.loadxml "<xml>1 2</xml>" 
wscript.echo len(xml.documentelement.text) 

Above druckt 3.

Dim xml: Set xml = CreateObject("MSXML2.DOMDocument") 
xml.async = False 
xml.loadxml "<xml> 2</xml>" 
wscript.echo len(xml.documentelement.text) 

Above druckt 1. (Ich möchte es 2 drucken).

Gibt es etwas Spezielles, das ich in das XML-Dokument selbst schreiben kann, um dem Parser zu sagen, dass er Leerzeichen im Dokument führen soll?

CLARIFICATION 1: Gibt es ein Attribut, das am Anfang des Dokuments EINMAL spezifiziert werden kann, um es auf alle Elemente anzuwenden?

KLARIFIZIERUNG 2: Da der Inhalt der Entitäten Unicode-Daten haben kann, aber die XML-Datei einfach ascii sein muss, sind alle Entitäten codiert - was bedeutet, dass CDATA leider nicht verfügbar sind.

+0

CDATA ist sicherlich vorhanden. Sie müssen möglicherweise nur mehr als einen pro Elementwert verwenden. –

+0

@michaelpryor: Über alle Antworten, die "xml: space" empfehlen. Dieses Problem hat nichts mit xml: space zu tun, das steuert, wie ein Parser whitespace-only-Knoten behandelt. Die gezeigten Knoten sind definitiv nicht nur Leerzeichen. Sehen Sie meine Lösung, die die einzige ist, die das Problem wirklich behandelt. Prost, –

+1

Das Problem hat * nichts * mit CDATA zu tun. CDATA ist nur zur Parsingzeit vorhanden, im Infoset ist es nicht mehr vorhanden und Whitespaces * sind * Teil des Infosets. – bortzmeyer

Antwort

8

Als ich bemerkte, alle Antworten die Nutzung des xml:space="preserve" sind falsch empfehlen.

xml:space Das Attribut kann nur die Behandlung verwendet wird zum Steuern Leerzeichen-only Knoten, dh Textknoten vollständig von Leerzeichen bestehen.

Dies ist bei dem aktuellen Problem nicht der Fall.

In der Tat, der folgende Code korrekt bereitgestellt erhält eine Länge von 2 für den Textknoten enthalten in:

<xml> 2</xml> 

Hier ist die VB-Code, der die Länge des Textknoten korrekt erhält (nicht vergessen Sie einen Verweis auf hinzuzufügen "Microsoft XML, v 3.0"):

Dim xml As MSXML2.DOMDocument 
Private Sub Form_Load() 
Set xml = CreateObject("MSXML2.DOMDocument") 
xml.async = False 
xml.loadxml "<xml> 2</xml>" 
Dim n 
n = Len(xml.documentelement.selectSingleNode("text()").nodeValue) 
wscript.echo Len(n) 
End Sub 

Wenn Sie einen Haltepunkt auf der Linie setzen:

wscript.echo Len(n) 

Sie sehen, dass wenn der Debugger dort bricht, der Wert n ist 2, wie es erforderlich ist.

Daher ist dieser Code die Lösung, die gesucht wurde.

+0

das Attribut xml: space = "preserve" funktionierte zwar. Ich weiß nicht, wer die Antworten gelöscht hat, die es vorgeschlagen haben, aber das hat gut für mich funktioniert. –

+2

@michaelpryor: Genauer gesagt, die Antwort auf die orig. q. ist: "Nein, nichts Besonderes muss in das XML-Dokument geschrieben werden, da der Parser keinen Nicht-Leerraum-Textknoten schneidet. Verwenden Sie einfach die Eigenschaft" nodeValue "und verwenden Sie nicht die Eigenschaft" text ". –

+0

In der Zeile welches weist 'n' einen Wert zu, sollten wir 'Len' haben? – Jaywalker

3

Sie könnten versuchen, es in einen CDATA-Block setzen:

<xml><![CDATA[ 2]]></xml> 
+0

An alle, die mit "xml: space" geantwortet haben: Dieses Problem hat nichts mit xml: space zu tun, das steuert, wie ein Parser whitespace - * only * nodes behandelt. Die gezeigten Knoten sind definitiv nicht nur Leerzeichen. –

+0

Laut meiner vorh. Kommentar Ich empfehle, dass Sie die falschen Antworten zurückziehen oder dass andere Leute sie komplett ablehnen. Prost, –

+0

Das Infoset ist genau das gleiche, mit oder ohne CDATA. Das ist nicht das Problem. – bortzmeyer

3

Wie von Dimitre Novatchev für XML erwähnt, wird Leerzeichen vom Parser nicht nach Wunsch gelöscht. Der Leerraum ist Teil des Werts des Knotens. Da ich Visual Basic nicht beherrsche, gibt es hier ein C-Programm mit libxml welches die Länge des ersten Textknotens ausgibt. Es gibt absolut keine Notwendigkeit, Xml: Space.Hier

% ./whitespace "<foo> </foo>" 
Length of " " is 1 

% ./whitespace "<foo> 2</foo>" 
Length of " 2" is 2 

% ./whitespace "<foo>1 2</foo>" 
Length of "1 2" is 3 

ist das Programm:

#include <stdio.h> 
#include <string.h> 
#include <libxml/parser.h> 

int 
main(int argc, char **argv) 
{ 
    char   *xml; 
    xmlDoc   *doc; 
    xmlNode  *first_child, *node; 
    if (argc < 2) { 
     fprintf(stderr, "Usage: %s XML-string\n", argv[0]); 
     return 1; 
    } 
    xml = argv[1]; 
    doc = xmlReadMemory(xml, strlen(xml), "my data", NULL, 0); 
    first_child = doc->children; 
    first_child = first_child->children;  /* Skip the root */ 
    for (node = first_child; node; node = node->next) { 
     if (node->type == XML_TEXT_NODE) { 
      fprintf(stdout, "Length of \"%s\" is %i\n", (char *) node->content, 
        strlen((char *) node->content)); 
     } 
    } 
    return 0; 
}