[英]How to properly create XML header (to fill pdf documents in xfdf format) with Delphi using IXMLDOCUMENT
please I need help to achieve this xml, I have a problme with the third line, this is what I get with my code:请我需要帮助来实现这个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>
and this is what I need:这就是我需要的:
<?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>
I dont know how to create the "f" tag like in the second example, notice that it's a little bit different and it closes in the same line and not before the last line like in the first example.我不知道如何像第二个示例中那样创建“f”标签,请注意它有点不同,它在同一行中关闭,而不是在第一个示例中的最后一行之前。
Here is my code:这是我的代码:
....
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');
you mixed node你混合节点
f is child xfdf f 是孩子 xfdf
filds is also child xfdf filds 也是孩子 xfdf
solution解决方案
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;
You are getting a bad result because:你得到一个糟糕的结果,因为:
you are not handling XML namespaces correctly.您没有正确处理 XML 名称空间。
you are creating the fields
node as a child of the f
node instead of as a child of the xfdf
node.您正在创建fields
节点作为f
节点的子节点而不是xfdf
节点的子节点。
When a child node is added, it inherits its parent node's namespace unless you explicitly specify a different namespace, and the namespace cannot be changed once assigned.添加子节点时,除非您明确指定不同的命名空间,否则它将继承其父节点的命名空间,并且命名空间一旦分配就无法更改。
In your case, your xfdf
node is not actually being added to the Adobe namespace, you are faking it!在您的情况下,您的xfdf
节点实际上并未添加到 Adobe 命名空间中,您是在伪造它! The XML engine does not know about the namespace, so the xfdf
node has a blank namespace, which the f
child node inherits. XML 引擎不知道命名空间,因此xfdf
节点有一个空白命名空间, f
子节点继承了它。 That is why the f
node ends up with the unwanted xmlns=""
attribute, so there is no ambiguity as it which namespace child nodes belong to.这就是为什么f
节点以不需要的xmlns=""
属性结束,因此没有歧义,因为它属于哪个命名空间子节点。
To declare a namespace correctly so the XML engine knows about it, you need to use the IXMLNode.DeclareNamespace()
method instead of using the IXMLNode.Attributes
property.要正确声明命名空间以便 XML 引擎知道它,您需要使用IXMLNode.DeclareNamespace()
方法而不是使用IXMLNode.Attributes
属性。
You can either:您可以:
explicitly declare the Adobe namespace on the xfdf
node after adding it to the document.将其添加到文档后,在xfdf
节点上显式声明 Adobe 命名空间。 The xfdf
node itself will not be in the namespace (as evident by the IXMLNode.NamespaceURI
property still being blank), but the namespace can then be explicitly applied when adding the f
and fields
child nodes: xfdf
节点本身不会在命名空间中(从IXMLNode.NamespaceURI
属性仍然为空白可以看出),但是在添加f
和fields
子节点时可以显式应用命名空间:
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;
alternatively, declare the Adobe namespace on the xfdf
node at the time you add that node to the document, and then that node will be in the namespace so the f
and fields
child nodes inherit it without you having to call DeclareNamespace()
manually ( AddChild()
calls it internally for you):或者,在您将该节点添加到文档时在xfdf
节点上声明 Adobe 命名空间,然后该节点将在命名空间中,因此f
和fields
子节点继承它,而无需手动调用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;
Either approach will remove the xmlns=""
attribute on the f
and fields
nodes since they belong to a namespace that is declared in the xfdf
node, and subsequent child nodes will inherit the namespace as expected:这两种方法都将删除f
和fields
节点上的xmlns=""
属性,因为它们属于在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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.