本文介绍了Inno Setup-XML编辑XPath请求失败,并带有“运行时NIL接口异常".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为我的应用程序创建了一个Inno Setup脚本,在该脚本中,我试图在安装后步骤(主要是连接字符串)中编辑一些XML配置.我有一些非常简单的XPath请求,但使用 selectSingleNode 时却遇到了运行时异常,而 getElementsByTagName 的效果很好.

I've created a Inno Setup script for my app in which I'm trying to edit some XML configuration in the post install step (mostly connection strings). I have some pretty simple XPath request but I have a runtime exception when using selectSingleNode whereas getElementsByTagName works perfectly fine.

此代码不起作用.它将抛出运行时NIL接口异常" .

This code does not work. It throws "NIL Interface Exception at runtime".

procedure ReadValueFromXML(const AFileName, APath, AAttribute, AValue: string);
var
  XMLNode: Variant;
  XMLDocument: Variant;
begin
  XMLDocument := CreateOleObject('Msxml2.DOMDocument');
  try
    XMLDocument.async := False;
    LOG(AFileName);
    XMLDocument.load(AFileName);
    if (XMLDocument.parseError.errorCode <> 0) then
      MsgBox('The XML file could not be parsed. ' +
        XMLDocument.parseError.reason, mbError, MB_OK)
    else
    begin
      XMLDocument.setProperty('SelectionLanguage', 'XPath');
      XMLNode := XMLDocument.selectSingleNode(APath);
      LOG(XMLNode.getAttribute(AAttribute));
      XMLDocument.save(AFileName);
    end;
  except
    MsgBox('An error occured!' + #13#10 + GetExceptionMessage, mbError, MB_OK);
  end;
end;

到目前为止,我一直在尝试用几个XPath请求来调用它:

So far I've been trying to call it with several XPath request :

  • ReadValueFromXML(FilePath,'//Phedre','ConnectionString',PhedreCon.Text)
  • ReadValueFromXML(FilePath,'//PhedreConfiguration/Databases/Phedre','ConnectionString',PhedreCon.Text)
  • ReadValueFromXML(FilePath,'/PhedreConfiguration/Databases/Phedre','ConnectionString',PhedreCon.Text)

另一方面,这很好用(记录连接字符串):

This, on the other hand, works fine (logs the connection strings) :

procedure ReadValueFromXML(const AFileName, APath, AAttribute, AValue: string);
var
  XMLNode: Variant;
  XMLDocument: Variant;
  Index: Integer;
begin
  XMLDocument := CreateOleObject('Msxml2.DOMDocument');
  try
    XMLDocument.async := False;
    LOG('Lecture du fichier ' + AFileName);
    XMLDocument.load(AFileName);
    if (XMLDocument.parseError.errorCode <> 0) then
      MsgBox('The XML file could not be parsed. ' +
        XMLDocument.parseError.reason, mbError, MB_OK)
    else
    begin
      XMLDocument.setProperty('SelectionLanguage', 'XPath');
      XMLNode := XMLDocument.getElementsByTagName(APath);
      for Index := 0 to XMLNode.length - 1 do
      begin
        LOG(XMLNode.item[Index].getAttribute(AAttribute));
      end;
    end;
  except
    MsgBox('An error occured!' + #13#10 + GetExceptionMessage, mbError, MB_OK);
  end;
end;

使用的XML是:

<PhedreConfiguration d1p1:schemaLocation="http://ns.edf.fr/phedre/config/v1.0 ./PhedreConfiguration.xsd" xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.edf.fr/phedre/config/v1.0">
    <Databases>
        <Phedre ConnectionString="Server=****; Port=3306; Database=****; Uid=****; Pwd=****;"/>
        <Arche ConnectionString="Server=****; Port=3306; Database=****;  Uid=****; Pwd=****;"/>
    </Databases>
    [...]
</PhedreConfiguration>

所以我的问题是:XPath请求中是否存在任何语法错误?为什么 getElementsByTagName('Phedre')起作用而 selectSingleNode('//Phedre')不能起作用?

So my question is: Is there any kind of syntax error in my XPath request? Why would getElementsByTagName('Phedre') work and selectSingleNode('//Phedre') won't?

推荐答案

由于@choroba的评论,我找到了解决方案.使用时,需要在XPath请求中指定名称空间.

Thanks to @choroba's comment I found the solution. Namespace needs to be specified in XPath request when used.

解决方案是在过程中设置选择名称空间:

The solution was to set selection namespace in the procedure:

XMLDocument.setProperty(
  'SelectionNamespaces', 'xmlns:ns=''http://ns.edf.fr/phedre/config/v1.0''');

并使用//ns:Phedre 进行调用.

这篇关于Inno Setup-XML编辑XPath请求失败,并带有“运行时NIL接口异常".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-11 01:21