我正在使用带有TXmlDocument
和IXmlNode
的Delphi 2007将xsi:type
属性设置为新的xml节点,但我得到的结果与预期不同。
with fieldNode do
begin
Attributes['xmlns:xsi'] := 'http://www.w3.org/2001/XMLSchema-instance';
Attributes['xmlns:xsd'] := 'http://www.w3.org/2001/XMLSchema';
Attributes['xsi:type'] := 'FieldImage';
Attributes['xmlns'] := '';
end;
我希望输出为:
<SerializableField xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="FieldImage" xmlns="">
但相反,我得到了:
<SerializableField xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="FieldImage" xmlns="">
缺少xsi:
部分。这是Delphi中的已知错误还是我做错了什么?
更新
使用下面答案中提供的控制台应用程序,生成的XML与预期的xsi:type
属性一致。我无法在我的应用中重新创建它。它是一个delphi.net应用程序,如果这有任何区别?
我已经制作了一个解决方法,即将XML转换为字符串并执行字符串替换,但这似乎没必要,而且有点脏......
答案 0 :(得分:0)
我在Delphi XE7 / Win10中制作了一个MVCE(你应该提供的):
program SO41263595;
{$APPTYPE CONSOLE}
uses
XmlIntf,
XmlDoc,
ActiveX,
SysUtils;
procedure Test;
var
Doc : IXMLDocument;
Node : IXMLNode;
begin
Doc := LoadXMLData('<test><node/></test>');
Node := Doc.DocumentElement.ChildNodes[0];
Node.Attributes['xmlns:xsi'] := 'http://www.w3.org/2001/XMLSchema-instance';
Node.Attributes['xmlns:xsd'] := 'http://www.w3.org/2001/XMLSchema';
Node.Attributes['xsi:type'] := 'FieldImage';
Node.Attributes['xmlns'] := '';
Writeln(Doc.XML.Text);
end;
begin
try
try
CoInitialize(nil);
Test;
finally
CoUninitialize;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
这给出了正确的输出:
<test><node xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="FieldImage" xmlns=""/></test>
如果此MVCE产生与您相同的问题,那么它可能是Delphi错误或MSXML库问题(TXMLDocument是一个包装器)。
答案 1 :(得分:0)
在声明XML命名空间(xmlns
属性)时,您应该使用IXMLNode.DeclareNamespace()
方法,不要直接使用IXMLNode.Attributes
属性。这样做只会创建属性,但不会让DOM知道命名空间实际存在。 DeclareNamespace()
将生成必要的xmlns
属性,并在DOM中注册名称空间,以便底层XML引擎在创建新节点/属性时可以使用它们。这很重要,这样子节点就可以正确地继承父节点的名称空间。
设置名称空间中的属性时,可以使用Attributes
属性,也可以使用IXMLNode.SetAttributeNS()
方法。
试试这个:
with fieldNode do
begin
DeclareNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
DeclareNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
Attributes['xsi:type'] := 'FieldImage';
// alternatively:
// SetAttributeNS('type', 'http://www.w3.org/2001/XMLSchema-instance', 'FieldImage');
DeclareNamespace('', '');
end;
这会产生预期的XML:
<SerializableField xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="FieldImage" xmlns="">