2016-10-03 255 views
2

正確創建XML標題(以pdf格式填充pdf文檔)請使用我需要幫助來實現這個xml,我有一個問題與第三行,這是我得到的代碼:如何正確使用IXMLDOCUMENT

<?xml version="1.0" encoding="utf-8"?> 
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve"> 
    <f xmlns="" href="myExample.pdf"> 
    <fields> 
     <field name="chk01"> 
     <value>X</value> 
     </field> 
     <field name="chk02"> 
     <value>X</value> 
     </field> 
     <field name="edt11"> 
     <value>Some text</value> 
     </field> 
    </fields> 
    </f> 
</xfdf> 

,這正是我需要的:

<?xml version="1.0" encoding="UTF-8"?> 
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">  
    <f href="myExample.pdf"/> 
    <fields> 
    <field name="chk01"> 
     <value>X</value> 
    </field> 
    <field name="chk02"> 
     <value>X</value> 
    </field> 
    <field name="edt11"> 
     <value>Some text</value> 
    </field> 
    </fields> 
</xfdf> 

我不知道如何在第二個例子中創建的「F」的標籤一樣,請注意,這是一個有點不同,它在關閉同一行,而不是像第一個例子中的最後一行。

這裏是我的代碼:

.... 
Var 
    XML : IXMLDOCUMENT; 
    RootNode, NodeLevel1, CurNode : IXMLNODE; 
Begin 
    XML := NewXMLDocument; 
    XML.Encoding := 'utf-8'; 
    XML.Options := [doNodeAutoIndent]; 

    RootNode := XML.AddChild('xfdf'); 
    RootNode.Attributes['xmlns']:= 'http://ns.adobe.com/xfdf/'; 
    RootNode.Attributes['xml:space']:= 'preserve'; 

    RootNode := XML.DocumentElement.AddChild('f'); 
    RootNode.Attributes['href']:= 'myExample.pdf'; 

    NodeLevel1 := RootNode.AddChild('fields'); 
    CurNode := NodeLevel1.AddChild('field'); 
    CurNode.Attributes['name'] := 'chk01'; 
    CurNode := CurNode.AddChild('value'); 
    CurNode.Text:= 'X'; 

    CurNode := NodeLevel1.AddChild('field'); 
    CurNode.Attributes['name'] := 'chk02'; 
    CurNode := CurNode.AddChild('value'); 
    CurNode.Text:= 'X'; 

    CurNode := NodeLevel1.AddChild('field'); 
    CurNode.Attributes['name'] := 'edt11'; 
    CurNode := CurNode.AddChild('value'); 
    CurNode.Text:= 'Some text'; 

XMl.SaveToFile('C:\New.fdf'); 

回答

1

你得到的結果不好,因爲:

  1. 您沒有正確處理XML名稱空間。

  2. 您正在創建fields節點作爲f節點的子節點,而不是作爲xfdf節點的子節點。

當添加子節點,它繼承了其父節點的命名空間,除非你明確指定一個不同的命名空間,命名空間不能改變分配一次。

在你的情況下,你的xfdf節點實際上並沒有被添加到你命名的Adobe命名空間 XML引擎不知道名稱空間,因此xfdf節點具有空白名稱空間,f子節點繼承該空白名稱空間。這就是爲什麼f節點最終會導致不需要的xmlns=""屬性,所以不存在任何歧義,因爲它是子節點所屬的名稱空間。

要正確聲明名稱空間以便XML引擎知道它,您需要使用IXMLNode.DeclareNamespace()方法而不是使用IXMLNode.Attributes屬性。

您可以:

  1. 顯式聲明xfdf節點上的Adobe的命名空間將它添加到文檔後。該xfdf節點本身將不會在命名空間(由IXMLNode.NamespaceURI屬性仍是空白爲明顯),但該命名空間就可以顯式應用添加ffields子節點時:

    const 
        NsAdobeXfdf = 'http://ns.adobe.com/xfdf/'; 
    var 
        XML: IXMLDocument; 
        RootNode, FNode, FieldsNode, FieldNode: IXMLNode; 
    begin 
        XML := NewXMLDocument; 
        XML.Encoding := 'utf-8'; 
        XML.Options := [doNodeAutoIndent]; 
    
        RootNode := XML.AddChild('xfdf'); // <-- xfdf is not in any namespace 
        RootNode.DeclareNamespace('', NsAdobeXfdf); // <-- declare the namespace 
        RootNode.Attributes['xml:space'] := 'preserve'; 
    
        FNode := RootNode.AddChild('f', NsAdobeXfdf); // <-- f is in the Adobe namespace 
        FNode.Attributes['href'] := 'myExample.pdf'; 
    
        FieldsNode := RootNode.AddChild('fields', NsAdobeXfdf); // <-- fields is in the Adobe namespace 
    
        FieldNode := FieldsNode.AddChild('field'); // <-- inherits namespace from fields 
        FieldNode.Attributes['name'] := 'chk01'; 
        FieldNode.AddChild('value').Text := 'X'; // <-- inherits namespace from field 
    
        FieldNode := FieldsNode.AddChild('field'); // <-- inherits namespace from fields 
        FieldNode.Attributes['name'] := 'chk02'; 
        FieldNode.AddChild('value').Text := 'X'; // <-- inherits namespace from field 
    
        FieldNode := FieldsNode.AddChild('field'); // <-- inherits namespace from fields 
        FieldNode.Attributes['name'] := 'edt11'; 
        FieldNode.AddChild('value').Text := 'Some text'; // <-- inherits namespace from field 
    
        XML.SaveToFile('C:\New.fdf'); 
    end; 
    
  2. 另外,申報當您將該節點添加到文檔時,xfdf節點上的Adobe命名空間,然後該節點將位於命名空間中,因此ffields子節點將繼承該節點,而無需手動撥打DeclareNamespace()AddChild()在內部爲您調用它):

    const 
        NsAdobeXfdf = 'http://ns.adobe.com/xfdf/'; 
    var 
        XML: IXMLDocument; 
        RootNode, FNode, FieldsNode, FieldNode: IXMLNode; 
    begin 
        XML := NewXMLDocument; 
        XML.Encoding := 'utf-8'; 
        XML.Options := [doNodeAutoIndent]; 
    
        RootNode := XML.AddChild('xfdf', NsAdobeXfdf); // <-- xfdf is in the Adobe namespace 
        RootNode.Attributes['xml:space'] := 'preserve'; 
    
        FNode := RootNode.AddChild('f'); // <-- inherits namespace from xfdf 
        FNode.Attributes['href'] := 'myExample.pdf'; 
    
        FieldsNode := RootNode.AddChild('fields'); // <-- inherits namespace from xfdf 
    
        FieldNode := FieldsNode.AddChild('field'); // <-- inherits namespace from fields 
        FieldNode.Attributes['name'] := 'chk01'; 
        FieldNode.AddChild('value').Text := 'X'; // <-- inherits namespace from field 
    
        FieldNode := FieldsNode.AddChild('field'); // <-- inherits namespace from fields 
        FieldNode.Attributes['name'] := 'chk02'; 
        FieldNode.AddChild('value').Text := 'X'; // <-- inherits namespace from field 
    
        FieldNode := FieldsNode.AddChild('field'); // <-- inherits namespace from fields 
        FieldNode.Attributes['name'] := 'edt11'; 
        FieldNode.AddChild('value').Text := 'Some text'; // <-- inherits namespace from field 
    
        XML.SaveToFile('C:\New.fdf'); 
    end; 
    
,因爲它們屬於那個在 xfdf節點聲明的命名空間

兩種方法都將刪除ffields節點上xmlns=""屬性,以及隨後的子節點將繼承如預期的命名空間:

<?xml version="1.0" encoding="utf-8"?> 
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve"> 
    <f href="myExample.pdf"/> 
    <fields> 
    <field name="chk01"> 
     <value>X</value> 
    </field> 
    <field name="chk02"> 
     <value>X</value> 
    </field> 
    <field name="edt11"> 
     <value>Some text</value> 
    </field> 
    </fields> 
</xfdf> 
+0

哇,非常感謝你的時間,如此清楚,並很好地解釋。我喜歡第二種方法,因爲它在代碼中少一點冗餘,子節點的名稱空間是從根節點繼承而來的,我不必再指定它。 – Jiug

+0

,當然結果如預期的那樣在節點「f」和「fields」中沒有不需要的屬性xmlns =「」。現在很清楚! :) – Jiug

+0

@Jiug:如果此答案解決了您的問題,請務必將其標記爲已接受。請參閱[當某人回答我的問題時該怎麼辦?](http://stackoverflow.com/help/someone-answers)。 –

1

你混合節點

f爲孩子XFDF

filds也是孩子XFDF

解決方案

Var 
XML : IXMLDOCUMENT; 
fnode, RootNode, NodeLevel1, CurNode : IXMLNODE; 
Begin 
XML := NewXMLDocument; 
XML.Encoding := 'utf-8'; 
XML.Options := [doNodeAutoIndent]; 

RootNode := XML.AddChild('xfdf'); 
RootNode.Attributes['xmlns']:= 'http://ns.adobe.com/xfdf/'; 
RootNode.Attributes['xml:space']:= 'preserve'; 

fnode := RootNode.AddChild('f'); 
fNode.Attributes['href']:= 'myExample.pdf'; 

NodeLevel1 := RootNode.AddChild('fields'); 
CurNode := NodeLevel1.AddChild('field'); 
CurNode.Attributes['name'] := 'chk01'; 
CurNode := CurNode.AddChild('value'); 
CurNode.Text:= 'X'; 

CurNode := NodeLevel1.AddChild('field'); 
CurNode.Attributes['name'] := 'chk02'; 
CurNode := CurNode.AddChild('value'); 
CurNode.Text:= 'X'; 

CurNode := NodeLevel1.AddChild('field'); 
CurNode.Attributes['name'] := 'edt11'; 
CurNode := CurNode.AddChild('value'); 
CurNode.Text:= 'Some text'; 

XMl.SaveToFile('C:\tmp\New.fdf');end; 
+0

它的工作原理!非常感謝,下面我有另外一個問題:) – Jiug

+0

更改行RootNode:= XML.addChild('xfdf')與 XML.DocumentElement:= XML.CreateElement('xfdf','http://ns.adobe的.com/XFDF /'); RootNode:= XML.DocumentElement;並刪除添加屬性xmlns – ceha

+0

再次感謝,現在它是完美的:) – Jiug