29.11.2011 13:42, Graeme Geldenhuys пишет:
On 29/11/2011, Sergei Gorelkin<sergei_gorel...@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


--
_______________________________________________
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to