请我需要帮助来实现此xml,第三行有一个问题,这就是我的代码所得到的:

<?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');

最佳答案

您收到的结果很糟糕,原因是:


您没有正确处理XML名称空间。
您正在将fields节点创建为f节点的子代,而不是作为xfdf节点的子代。


添加子节点时,除非您显式指定其他名称空间,否则它将继承其父节点的名称空间,并且一旦分配该名称空间就无法更改。

在您的情况下,您的xfdf节点实际上并未添加到Adobe名称空间中,您是在伪造它! XML引擎不知道名称空间,因此xfdf节点有一个空白的名称空间,它是f子节点继承的。这就是为什么f节点以不需要的xmlns=""属性结尾的原因,因此没有歧义,因为它属于哪个名称空间子节点。

要正确声明一个名称空间,以便XML引擎知道它,您需要使用IXMLNode.DeclareNamespace()方法而不是使用IXMLNode.Attributes属性。

您可以:


将Adobe名称空间添加到文档后,在xfdf节点上显式声明。 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;

或者,在将该节点添加到文档时,在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;



两种方法都将删除xmlns=""f节点上的fields属性,因为它们属于在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>

关于xml - 如何使用IXMLDOCUMENT使用Delphi正确创建XML header (以xfdf格式填充pdf文档),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39827589/

10-09 05:34