Можете ли вы сохранить начальные и конечные пробелы в XML? - PullRequest
9 голосов
/ 06 января 2009

Как можно заставить синтаксический анализатор XML соблюдать начальные и конечные пробелы?

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

Выше распечатывается 3.

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

Выше напечатано 1. (Я бы хотел напечатать 2).

Есть ли что-то особенное, что я могу добавить в сам документ xml, чтобы сказать парсеру, чтобы он оставался в начале и в конце пробела в документе?

РАЗЪЯСНЕНИЕ 1 : Есть ли атрибут, который можно указать ОДИН РАЗ в начале документа, чтобы применить ко всем элементам?

РАЗЪЯСНЕНИЕ 2 : поскольку содержимое сущностей может иметь данные в кодировке Юникод, но файл xml должен быть простым ascii, все сущности закодированы - то есть CDATA, к сожалению, недоступны.

Ответы [ 3 ]

8 голосов
/ 06 января 2009

Как я уже говорил, все ответы, рекомендующие использовать xml:space="preserve", неверны .

Атрибут xml:space может использоваться только для управления обработкой только пробельных узлов , то есть текстовых узлов, состоящих из полностью из пробельных символов.

Это совсем не относится к текущей проблеме.

Фактически, приведенный ниже код правильно получает длину 2 для текстового узла, содержащегося в:

<xml> 2</xml>

Вот код VB, который правильно получает длину текстового узла (не забудьте добавить ссылку на «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

Если вы поставили точку останова на линии:

wscript.echo Len(n)

вы увидите, что когда отладчик ломается, значение n равно 2, как и требуется.

Следовательно, этот код является решением , которое искали.

3 голосов
/ 06 января 2009

Как отметил Дмитрий Новатчев, для XML пробелы не удаляются по желанию парсера. Пробел является частью, если узел значение. Так как я не говорю на Visual Basic, вот программа на C с libxml , которая печатает длину первого текстового узла. Есть абсолютно не нужно устанавливать xml: space.

% ./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

Вот программа:

#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;
}
3 голосов
/ 06 января 2009

вы можете попробовать поместить его в блок CDATA:

<xml><![CDATA[ 2]]></xml>
...