9

如何告诉 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:因为实体的内容可能有 unicode 数据,但 xml 文件需要是纯 ascii,所有实体都经过编码——这意味着 CDATA 很遗憾不可用。

4

2 回答 2

8

正如我评论的那样,所有推荐使用的答案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)

您会看到,当调试器中断时, 的值为n2,这是必需的。

因此,此代码是正在寻求的解决方案。

于 2009-01-06T04:50:46.873 回答
4

正如 Dimitre Novatchev 所提到的,对于 XML,解析器不会随意删除空格。空格是节点值的一部分。因为我不会说 Visual Basic,所以这里有一个带有 libxml的 C 程序,它打印第一个文本节点的长度。绝对不需要设置 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;
}
于 2009-01-06T10:04:54.370 回答