Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 5 of 5 total
Thread XML parsing
Wed, Jun 12 2013 6:31 AMPermanent Link

Matthew Jones

I'd much appreciate a primer on using the XML TDocument a bit better.

I know how to use
xDOM := ParseXML(szXML); // OLD getDOMfromXMLstring(szXML);
to get the TDocument.

I know how to use
   xDataNodeList := xDOM.getElementsByTagName('Anonymous');
to get a list of nodes from within the XML.

But I want to traverse the XML better, and get attributes. Take the following XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<User id="6">
 <JoinCode>matthew</JoinCode>
</User>

How can I read the 'id' value from the root 'User' node. How can I get the value of
the 'JoinCode' node?

I would normally do something like: (forgive the x "hungarian" which means object)
xRootNode := xDOM.RootNode;
szID := xRootNode.Attribute['id'];
xJoinNode := xRootNode.ChildNodeByName('JoinCode');
szJoinCode := xJoinNode.NodeText;

(Ignoring possible nil values for children etc for now).

Now, in webdom.wbs, TDocument is derived from TNode. It has a documentElement which
is a TElement. A TElement is also a TNode, but has useful things like getAttribute,
which looks sensible. TElement doesn't have much else, but TNode has
selectSingleNode which returns a TNode. I assume that's an XPath type thing, but
can I assume the TNode is a TElement to get its value? Hmm, TNode has nodeValue, so
that might be it.

So, I get to:

var
   xDOM : TDocument;
   xRootNode : TElement;
   xJoinNode : TNode;
....
   xDOM := ParseXML(szXML);
   xRootNode := xDOM.documentElement;
   szID := xRootNode.getAttribute('id');
   xJoinNode := xRootNode.selectSingleNode('JoinCode');
   if assigned(xJoinNode) then
        szJoinCode := xJoinNode.nodeValue;

This is not working, as it gives an error that the "Object#<Element> has no method
'selectSingleNode'". But the 'id' is read correctly. selectNodes doesn't exist
either. Switching to IE10, and both "run", but neither returns the value.

I would welcome the input of the javascript DOM experienced on how I might do this
reliably.

/Matthew Jones/
Wed, Jun 12 2013 7:51 AMPermanent Link

Matthew Jones

These two functions seem to work for me. They are based on my Delphi code functions
of the same name.

function xml_ChildNodeByName(xNode : TNode; szNodeName : String) : TNode;
var
   xNodeList : TNodeList;
begin
   Result := nil;
   if IsIE then
   begin
       Result := xNode.selectSingleNode(szNodeName);
   end
   else
   begin
       xNodeList := xNode.ownerDocument.getElementsByTagName(szNodeName);
       if xNodeList.Length > 0 then
       begin
           Result := xNodeList[0]; // .firstChild;
       end;
   end;
end;

function xml_NodeText(xNode : TNode) : String;
begin
   if assigned(xNode) then
   begin
       Result := xNode.firstChild.nodeValue;
   end
   else
   begin
       Result := '';
   end;
end;

which gives:

   xJoinNode := xml_ChildNodeByName(xRootNode, 'JoinCode');
   if assigned(xJoinNode) then
        szJoinCode := xml_NodeText(xJoinNode);

Note that this is not strictly wholesome, as the child node is not actually found
by looking at the children, but by a wider search. It works for me though, as my
XML is simple. YMMV.

/Matthew Jones/
Wed, Jun 12 2013 8:54 AMPermanent Link

Matthew Jones

One small request, for Delphi-like improvement, TNodeList would be good with a
Count property (or function) that just called the length property. I don't know if
this is possible, but it doesn't seem natural to not have Count for looping through
a list. If not possible, a compiler hint to say "no Count, use length" would be
good. Or heck, if you go that far, and it ends with "List" then quietly just making
Count into Length would be even better.

Not a big thing, just a Delphi compatibility idiom.

/Matthew Jones/
Wed, Jun 12 2013 1:25 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Matthew,

<< One small request, for Delphi-like improvement, TNodeList would be good
with a Count property (or function) that just called the length property. >>

Sorry, but the external class interfaces must stick to the actual DOM
properties/methods/events - you can't "decorate" an external class with new
properties or methods that don't exist in the actual external class.   Well,
you can "kinda-sorta" do so with properties, but that's a different thing
that's outside the scope of this topic.

Tim Young
Elevate Software
www.elevatesoft.com

Sun, Sep 29 2013 11:11 AMPermanent Link

Ronald

Hi Matthew,

Maybe a littele late, but today I was trying to get attributes too and I
fond this to be working:

Enclosure:=ItemNodes[t1].selectSingleNode('enclosure');
ShowMessage(TElement(Enclosure).getAttribute('url'));

Enclosure is a TNode here.

Greetings,
Ronald


"Matthew Jones"  schreef in bericht
news:memo.20130612113123.9068B@nothanks.nothanks.co.uk...

I'd much appreciate a primer on using the XML TDocument a bit better.

I know how to use
xDOM := ParseXML(szXML); // OLD getDOMfromXMLstring(szXML);
to get the TDocument.

I know how to use
   xDataNodeList := xDOM.getElementsByTagName('Anonymous');
to get a list of nodes from within the XML.

But I want to traverse the XML better, and get attributes. Take the
following XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<User id="6">
 <JoinCode>matthew</JoinCode>
</User>

How can I read the 'id' value from the root 'User' node. How can I get the
value of
the 'JoinCode' node?

I would normally do something like: (forgive the x "hungarian" which means
object)
xRootNode := xDOM.RootNode;
szID := xRootNode.Attribute['id'];
xJoinNode := xRootNode.ChildNodeByName('JoinCode');
szJoinCode := xJoinNode.NodeText;

(Ignoring possible nil values for children etc for now).

Now, in webdom.wbs, TDocument is derived from TNode. It has a
documentElement which
is a TElement. A TElement is also a TNode, but has useful things like
getAttribute,
which looks sensible. TElement doesn't have much else, but TNode has
selectSingleNode which returns a TNode. I assume that's an XPath type thing,
but
can I assume the TNode is a TElement to get its value? Hmm, TNode has
nodeValue, so
that might be it.

So, I get to:

var
   xDOM : TDocument;
   xRootNode : TElement;
   xJoinNode : TNode;
....
   xDOM := ParseXML(szXML);
   xRootNode := xDOM.documentElement;
   szID := xRootNode.getAttribute('id');
   xJoinNode := xRootNode.selectSingleNode('JoinCode');
   if assigned(xJoinNode) then
        szJoinCode := xJoinNode.nodeValue;

This is not working, as it gives an error that the "Object#<Element> has no
method
'selectSingleNode'". But the 'id' is read correctly. selectNodes doesn't
exist
either. Switching to IE10, and both "run", but neither returns the value.

I would welcome the input of the javascript DOM experienced on how I might
do this
reliably.

/Matthew Jones/
Image