2009-01-05 43 views
9

如何告訴XML解析器遵守前導和尾隨空白?你能保留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文檔本身告訴解析器保持文檔中的前導空白和尾隨空白?

CLARIFICATION 1:是否有一個屬性可以在文檔的開始處指定爲一次,以應用於所有元素?由於實體的內容可能具有unicode數據,但xml文件需要爲純ASCII格式,因此所有實體都被編碼 - 這意味着CDATA的遺憾是不可用的。

+0

CDATA肯定是可用的。不過,您可能只需要使用多個元素值。 – 2009-01-05 21:58:50

+0

@michaelpryor:關於推薦「xml:space」的所有答案。這個問題與xml:space無關,它控制解析器如何處理空白*僅*節點。顯示的節點絕對不是空白的。看到我的解決方案,這是唯一真正處理問題的解決方案。歡呼聲, – 2009-01-06 04:53:42

+1

這個問題與CDATA無關。 CDATA僅在解析時存在,在信息集中,它不再存在,空白*是信息集的一部分。 – bortzmeyer 2009-01-06 10:05:56

回答

8

正如我評論,推薦的xml:space="preserve"的使用所有的答案都是錯誤

xml:space屬性只能被用於控制治療空格只節點,即由的空白字符完全文本節點。

這不是目前的問題。

事實上,下面正確地提供的代碼獲得含有2爲文本節點的長度:

<xml> 2</xml> 

這裏是VB代碼,正確地獲取文本節點的長度(不忘了添加引用 「微軟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

你可以嘗試把它變成一個CDATA塊:

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

正如Dimitre Novatchev所述,對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; 
}