2

请我需要帮助来实现这个 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');
4

2 回答 2

1

你得到了一个不好的结果,因为:

  1. 您没有正确处理 XML 命名空间。

  2. 您正在将节点创建为fields节点的子f节点,而不是节点的子xfdf节点。

添加子节点时,它会继承其父节点的命名空间,除非您明确指定不同的命名空间,并且命名空间一旦分配就不能更改。

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

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

您可以:

  1. 将 Adob​​e 命名空间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;
    
  2. 或者,在将节点添加到文档时在节点上声明 Adob​​e 命名空间xfdf,然后该节点将位于命名空间中,因此子节点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;
    

任何一种方法都将删除and节点xmlns=""上的属性,因为它们属于在节点中声明的命名空间,并且后续子节点将按预期继承命名空间:ffieldsxfdf

<?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>
于 2016-10-03T20:29:25.560 回答
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;
于 2016-10-03T09:57:28.463 回答