微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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.

原文地址:https://www.jb51.cc/xml/292353.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。