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 : すべての要素に適用するために、ドキュメントの先頭に 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)

nデバッガーがそこで中断すると、必要なため、 の値が 2 であることがわかります。

したがって、このコードは求められていた解決策です。

于 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 に答える