更改XML节点属性值会显示“名称空间错误”。 [英] Changing XML node attribute value gives "Namespace error"

查看:84
本文介绍了更改XML节点属性值会显示“名称空间错误”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用TXMLDocument创建XML文档。有时我需要更改属性值。如果使用 ADOM XML v4 DOM供应商(Delphi XE2),则会收到名称空间错误。

I use TXMLDocument to create XML documents. Sometimes I need to change attribute values. I get a "Namespace error" if I use the "ADOM XML v4" DOM vendor (Delphi XE2).

示例代码:

procedure TForm1.Button1Click(Sender: TObject);
var
  XML: TXMLDocument;
  XMLNode, XMLSubNode: IXMLNode;
begin
  XML := TXMLDocument.Create(nil);
  //XML.DOMVendor := GetDOMVendor('MSXML'); // Works using MSXML
  XML.DOMVendor := GetDOMVendor('ADOM XML v4');
  XML.Active := True;
  XMLNode := XML.AddChild('test');
  XMLNode.Attributes['state'] := 1;
  XMLNode.Attributes['state'] := 0; // Raises "Namespace error"
end;

如果我使用MSXML,则一切正常。我想使用ADOM XML,因为我正在生成大型XML文件,它似乎比MSXML快得多。

If I use MSXML, then everything works fine. I want to use ADOM XML because I'm generating large XML files and it seems to be a lot faster than MSXML.

如何更改属性值?

推荐答案

这是一个错误。也相当重要。使用ADOM XML供应商的当前实现,如果在null命名空间中创建属性,则无法更改其值。

This is a bug. A pretty major one too. With the current implementation of the ADOM XML vendor, if you create an attribute in the null namespace, you cannot change its value.

这是来自AdomCore_4_3单元的有问题的代码

Here is the offending code from the AdomCore_4_3 unit, as bundled with Delphi 2010.

procedure TDomAttr.SetPrefix(const Value: WideString);
begin
  if IsReadonly then
    raise ENo_Modification_Allowed_Err.Create('No modification allowed error.');

  if NodeName = 'xmlns' then
    raise ENamespace_Err.Create('Namespace error.');

  if NamespaceURI = 'http://www.w3.org/2000/xmlns/' then begin
    if Value <> 'xmlns' then
      raise ENamespace_Err.Create('Namespace error.');
  end else if NamespaceURI = 'http://www.w3.org/XML/1998/namespace' then begin
    if Value <> 'xml' then
      raise ENamespace_Err.Create('Namespace error.');
  end else begin
    if NamespaceURI = '' then
      raise ENamespace_Err.Create('Namespace error.');
    if Value = 'xml' then
      raise ENamespace_Err.Create('Namespace error.');
    if Value = 'xmlns' then
      raise ENamespace_Err.Create('Namespace error.');
  end;

  if Value = '' then begin
    if (NamespaceURI = 'http://www.w3.org/2000/xmlns/') then
      raise ENamespace_Err.Create('Namespace error.');
    FPrefix := '';
    FNodeName := LocalName;
    Exit;
  end;

  if not IsXmlName(Value) then
    raise EInvalid_Character_Err.Create('Invalid character error.');
  if not IsXmlPrefix(Value) then
    raise ENamespace_Err.Create('Namespace error.');

  FPrefix := Value;
  FNodeName := Concat(Value, ':', LocalName);
end;

在上面,问题可以隔离到这里...

In the above, the issue can be isolated to here...

    if NamespaceURI = '' then
      raise ENamespace_Err.Create('Namespace error.');



解决方法1



我有不知道作者的意图是什么,但就目前而言,这个测试是胡说八道。要解决此问题,请删除此测试并重新编译。

Work-around 1

I have no idea what the author's intent was, but as it stands, this test is nonsense. To fix, remove this test and recompile.

作为替代方案,您可以删除像这样设置之前的属性...

As an alternative, you could delete the attribute before setting like this ...

procedure TForm6.Button1Click(Sender: TObject);
var
  XML: TXMLDocument;
  XMLNode, XMLSubNode: IXMLNode;
  OldAttrib: IXMLNode;
begin
  XML := TXMLDocument.Create(nil);
  //XML.DOMVendor := GetDOMVendor('MSXML'); // Works using MSXML
  XML.DOMVendor := GetDOMVendor('ADOM XML v4');
  XML.Active := True;
  XMLNode := XML.AddChild('test');
  XMLNode.Attributes['state'] := 1;
  OldAttrib := XMLNode.AttributeNodes.FindNode('state');
  if assigned( OldAttrib) then
    XMLNode.AttributeNodes.Remove( OldAttrib);
  XMLNode.Attributes['state'] := 0; 
end;

这篇关于更改XML节点属性值会显示“名称空间错误”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆