1

I've read through CodeAutomation.iss and a bunch of other sources, but I couldn't find the answer to this...

Using the example provided, the xml objects are put in variables of the "Variant" type. I assume this is just the equivalent of 'var'.

However, when I try to check if such a variable is nil after doing a selectSingleNode, the compiler complains with "type mismatch".

Is there any way to check whether such a node fetch failed? What does it return to Inno if it found nothing?

Nyerguds
  • 5,360
  • 1
  • 31
  • 63
  • Could you show the code you have used ? I can't find `selectSingleNode` in any InnoSetup example. – TLama May 08 '13 at 09:49
  • That was one of my problems too, but it's in the xml DOM specs. This question has an answer where it's used: http://stackoverflow.com//questions/8194209/adding-a-node-to-an-existing-xml-file-using-inno-setup ...but as you see it's used unsafely, without null check. – Nyerguds May 08 '13 at 10:37
  • 1
    Well, but in this case the `selectSingleNode` behaves somehow strange. That's the reason why I haven't used [`this check for NULL`](http://stackoverflow.com/a/11254218/960757). The `selectSingleNode` returns always a non `NULL` value (at least on Windows 7) even if the node is not found by XPath. I would definitely use a `try.except` block as you'll need to catch more than just this node selection. – TLama May 08 '13 at 10:48
  • I kinda wanted to write a general querying method for an xpath that returns either the node or nil, which I can then call for about a dozen nodes I need to add/delete. Since the object can't contain nil, that idea is thoroughly out the window. – Nyerguds May 08 '13 at 11:15
  • 1
    It gets worse... I get a mysterious "Cannot import VARARRAYGET" error when trying to iterate over nodes retrieves with `selectNodes(String)` - EDIT - nevermind.. had to do .Item[] instead of just [] – Nyerguds May 08 '13 at 12:56
  • FWIW, `nil` is a null pointer value. A null variant is a completely different value. (The same is true in C++ -- you have to use different functions to check if a variant is empty than if a pointer is null.) – Miral May 08 '13 at 20:44
  • To extend @Miral's thought, there's a `NULL` value available in InnoSetup, although the proper way is to use `VarIsNull` function. – TLama May 08 '13 at 21:39

2 Answers2

3

You can test your Variant variable with the VarIsNull function.

TLama
  • 75,147
  • 17
  • 214
  • 392
  • Oh wow... that's rather dumb if the language has a "nil" for that. You'd think they can somehow treat that as equivalent. Thanks! – Nyerguds May 08 '13 at 10:36
  • You're welcome! Even if I've answered your question, testing a variable for `NULL` after `selectSingleNode` method call is useless by my experience. The method always returned me on Windows 7 a non `NULL` value despite the fact the XPath didn't found the node. – TLama May 08 '13 at 10:59
1

Just check node lenght result. This example select a node by its attribute name via XPath

XMLDocument.setProperty('SelectionLanguage', 'XPath');
XMLNode := XMLDocument.selectNodes('//' + ANodeName + '[@name="' + AttName + '"]');
   if (XMLNode.Length <= 0) then
   begin
      XMLNode := XMLDocument.selectSingleNode(APath);
      NewNode := XMLDocument.createElement(ANodeName);
      NewNode.setAttribute['type'] := AttrType; 
      NewNode.setAttribute['name'] := AttName; 
      NewNode.setAttribute['value'] := AttrValue; 

      XMLNode.appendChild (NewNode);
      XMLNode.lastChild.text := ANodeText;
      XMLDocument.save(AFileName);
   end;
  • Even though this doesn't answer the question being posed (how to check for null) it does provide the way to check if the node exists or not, since selectSingleNode always returns a non-null value. – Chris Apr 05 '19 at 14:08