[Lazarus] How to get the package version from a LPK file?

Sergei Gorelkin sergei_gorelkin at mail.ru
Tue Nov 29 15:53:27 CET 2011


29.11.2011 13:42, Graeme Geldenhuys пишет:
> On 29/11/2011, Sergei Gorelkin<sergei_gorelkin at mail.ru>  wrote:
>> To add to this, the core DOM is simply not supposed to do things like path
>> navigation.
>
> OK, then lets simplify the problem and remove the usage of a "node
> path". Can you solve to original problem using FPC DOM, but doing it
> one node retrieval at a time. eg:
>
>     xmdoc := TXMLDoc.loadfromfile('the package.lpk')'
>     configenode := xmldoc.<something here>'
>     packagenode := confignode.<something here>
>     versionnode := packagenode.<something here>
>     major_value := versionnode.<something here>
>
>
> If the FPC DOM is so per W3C spec, surely the W3C spec covers retrieve
> of  simple node somewhere in the XML file? I would just like to know
> how - so I can LEARN something today.
>
>
Core DOM includes the following navigation features:
1) Iterating forward: FirstChild, NextSibling properties. Requires a hand-written loop:

var n: TDOMNode;
begin
   n:=node.FirstChild;
   while assigned(n) do
   begin
     doSomething(n);
     n:=n.NextSibling;
   end;
end;

2) Iterating backwards: the same as above, but using LastChild and PreviousSibling properties.

3) Getting all *immediate* children of a node as a "list".
var
   list: TDOMNodeList;
begin
   list:=node.ChildNodes;
   for i:=0 to list.count-1 do
     doSomething(list[i]);
end;

4) Getting *recursive* list of all elements with given name: GetElementsByTagName('foo');
this is not a method of generic TDOMNode, but of TDOMElement and TDOMDocument classes (only these 
classes can contain child elements).

An important thing to note is that attributes are *not* the part of node tree and can not be 
navigated using the above methods. To work with attributes, you first have to locate the element to 
which the attributes belong, then get the attribute node using Element.Attributes[i] property, or 
Element.GetAttributeNode('foo'), or get directly the attribute value as Element['foo'];

Michael has already posted a good example. However, the original Silvio's code can be made working 
with minimal modifications, as follows:

var
   VXML: TXMLDocument;
   el: TDOMElement;
begin
   try
     ReadXMLFile(VXML, ExtractFilePath(ParamStr(0)) + 'LazSolutionsDT.lpk');
     el:=TDOMElement(vxml.GetElementsByTagName('Version').Item[1]);
     writeln(el['Minor'],'.',el['Release']);
   finally
     VXML.Free;
   end;
end.

Michael's example is more robust and efficient, because it does not depend on actual position of 
'Version' element, and it stops as soon as it finds the required element (while this example 
collects all 'Version' elements in document). This example is of course shorter.

Regards,
Sergei





More information about the Lazarus mailing list