XML:未安装MSXML

使用此代码获取站点RSS.此代码适用于我的计算机和许多其他计算机.但在某些计算机( Windows XP或7)中,我收到此错误:MSXML未安装

我该如何解决这个问题?怎么了?

这是代码

procedure My_Thread.Execute;
var
  http                 : tidhttp;
  strm                 : tmemorystream;
  str,sTitle,sDec,er : string;
  StartItemNode        : IXMLNode;
  ANode                : IXMLNode;
  XMLDoc               : IXMLDocument;

begin
  http := tidhttp.Create();
  strm := tmemorystream.Create;
    try
      http.Get('http://www.sample.com/RSS.xml',strm);     //Download the RSS file
      SetString(str,PANSIChar(strm.Memory),strm.Size);

      XMLDoc :=  LoadXMLData(str);

      StartItemNode := XMLDoc.DocumentElement.ChildNodes.First.ChildNodes.FindNode('item');
      ANode         := StartItemNode;

      i := 0;
      repeat
        inc(i);
        sTitle    := ANode.ChildNodes['title'].Text;
        sDec       := ANode.ChildNodes['description'].Text;
        Synchronize(procedure begin            //Synchronize? I'm using threads
          case I of
            1: begin
                 main_frm.edit1.text := sTitle; //main_frm is my form
                 main_frm.edit2.text := sDec;
               end;
            2: begin
                 main_frm.edit3.text := sTitle;
                 main_frm.edit4.text := sDec;
               end;
            3: begin
                 main_frm.edit5.text := sTitle;
                 main_frm.edit6.text := sDec;
               end;
          end;
          ANode := ANode.NextSibling;
        end);
      until ANode = nil;

      http.Free;
      strm.Free;

    except
      on E: Exception do
        begin
          er := e.Message;
          Synchronize(procedure begin
            ShowMessage(er);
          end);
        end;
    end;
end;

如你所见,我正在使用线程.所以需要Synchronize.

在Windows上,TXMLDocument认使用MSXML,它使用COM对象.您的线程在加载XML之前没有调用CoInitialize / Ex(),因此COM无法实例化IXMLDocument在内部尝试创建的任何MSXML COM对象(它尝试创建多个COM对象以发现实际上哪个版本的MSXML安装).您看到的错误消息表示所有MSXML COM对象都无法实例化.

您必须在访问COM对象的每个线程上下文中调用CoInitialize / Ex(),例如:

procedure My_Thread.Execute;
var
  ...
begin
  CoInitialize(nil);
  try
    ...
    XMLDoc := LoadXMLData(str);
    try
     ...
    finally
      // Since CoInitialize() and CoUninitialize() are being called in the same
      // method as local COM interface variables,it is very important to release
      // the COM interfaces before calling CoUninitialize(),do not just let them
      // release automatically when they go out of scope,as that will be too late...
      StartItemNode := nil;
      ANode := nil;
      XMLDoc := nil;
    end;
    ...
  finally
    CoUninitialize;
  end;
end;

更新:如果您不想依赖于此:您可以使用您选择的其他XML库,您不必使用MSXML:

Using the Document Object Model

Selecting an XML vendor

When you build an application,RAD Studio uses the default built-in XML vendor,MSXML.

If you do not specify a different XML vendor,your application does not have XML support on other platforms than Windows,and you see a run-time exception when you run your application in other platforms. For cross-platform applications,OmniXML is currently the best choice,as it shows much better performance than ADOM.

To choose a different XML vendor,07001 to the unit of the vendor into the unit where you use the RTL XML features,such as the 07002 class. If you add more than one XML vendor unit,the first unit referenced is used as XML vendor. If you need to override this behavior,change the value of the 07003 global variable to the global variable of the XML vendor that you want to use.

Note: You can look up the unit and the global variable of each XML vendor in the 07004 above.

When you use the 07002 component,you can choose an XML vendor using its 07006 property. When you change the value of 07006,the unit that uses the component is configured to use the specified XML vendor,so that you do not need to change unit references or the 07003 global variable manually.

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念