EldoS | Feel safer!

Software components for data protection, secure storage and transfer

XML and DOM basic questions

Also by EldoS: BizCrypto
Components for BizTalk® and SQL Server® Integration Services that let you securely store and transfer information in your business automation solutions.
#15752
Posted: 02/14/2011 11:53:32
by Leonardo Herrera (Standard support level)
Joined: 02/14/2011
Posts: 66

Hello,

I'm currently evaluating the SecureBlackBox package and I'm really happy with it. I'm still doing some basic stuff and finding my way around the components.

My application involves doing some SSL connections, obtaining tokens and signing. I need to parse returned XML strings and also create my own documents myself. I was using some external XML DOM object, but I figured since I'm getting this package anyways I should refrain of using too many component providers and keep using TElXMLDOMDocument and friends.

Now, onto some questions:

1) Many XML processors use "nodeValue" as a shortcut to get the text inside a given node. So, given the following XML:

Code
<?xml version="1.0" encoding="UTF-8" ?>
<XX:RESPONSE xmlns:XX="http://www.XX.xx/XMLSchema">
<XX:HDR>
   <ESTADO>00</ESTADO>
</XX:HDR>
<XX:BODY>
   <SEED>000000000078</SEED>
</XX:BODY>
</XX:RESPONSE>


the following code works:

Code
str := domobj.getElementsByTagName('SEED')[0].nodeValue; // returns '000000000078'


However, ElXML objects are much more restrictive in this matter, specially regarding nodeValue. Now, I understand what a #text node is, but my question is, do you have utility methods to deal with this stuff?

2) Elaborating above, is there an easy way to get a node and its contents using XPath? I found SelectNodes() but I spent quite some time trying to convert an XMLNode to XMLElement...

3) On the same vein, some parsers contain a "text" member which is just the inner text of the node plus the concatenated text of its descendants. Is there an already implemented method to get this functionality given a specific node? (not element)

4) GetElementsByTagName('SEED') didn't work for me using the same XML above (I'm pretty sure there is a reasonable explanation but I couldn't find it.) SelectNodes() worked but then I got the problem of converting the first note into an XMLNode. I know I'm pretty daft sometimes, but can you please add some short recipes on how to get elements and their text using your XML components?

That's it for now. I think I repeated myself in the questions above, but I don't have Delphi here at work so I'm pretty much typing from memory.

Thanks in advance,
Leonardo Herrera
#15753
Posted: 02/14/2011 12:43:21
by Dmytro Bogatskyy (EldoS Corp.)

Quote
1.
However, ElXML objects are much more restrictive in this matter, specially regarding nodeValue. Now, I understand what a #text node is, but my question is, do you have utility methods to deal with this stuff?

There are two methods in SBXMLUtils unit:
function GetTextFromXMLElement(const Element: TElXMLDOMElement): XMLString;
function GetStrictTextFromXMLElement(const Element: TElXMLDOMElement): XMLString;
that will return text from the selected element.
For example:
< body>Te<br />xt</ body>
the first method will return "Text", and a second will throw exception as it allows only text and entities under the selected element.

Quote
2) Elaborating above, is there an easy way to get a node and its contents using XPath? I found SelectNodes() but I spent quite some time trying to convert an XMLNode to XMLElement...

What XPath expression did you use?
For example to select Signature element you can use a following code:
Code
NSMap : TElXMLNamespaceMap := TElXMLNamespaceMap.Create;
NSMap.AddNamespace('ds', SBXMLDefs.xmlSignatureNamespace);
try
  NodeSet : TElXMLNodeSet := XMLDocument.SelectNodes('//ds:Signature', NSMap);
  for i := 0 to NodeSet.Count - 1 do
    if NodeSet[i].NodeType = ntElement then
    begin
      TElXMLDOMElement(NodeSet[i])  // process element
    end;

  FreeAndNil(NodeSet);
finally
  FreeAndNil(NSMap);
end;


Quote
3) On the same vein, some parsers contain a "text" member which is just the inner text of the node plus the concatenated text of its descendants. Is there an already implemented method to get this functionality given a specific node? (not element)

I think you are talking about InnerText method, it is not supported at the moment, only InnerXML property is supported. We will add it in the next build.

Quote
4) GetElementsByTagName('SEED') didn't work for me using the same XML above (I'm pretty sure there is a reasonable explanation but I couldn't find it.)

You are invoking GetElementsByTagName method from DocumentElement? Then it could be a problem. As GetElementsByTagName method search for direct childs only.
You can use SelectNodes method, or use FindElementByName method from SBXMLUtils that will search for first occurrences of the element.
For example:
Code
El : TElXMLDOMElement := SBXMLUtils.FindElementByName(Doc.DocumentElement, 'SEED', ''); // last parameter is NamespaceURI
#15755
Posted: 02/14/2011 12:54:23
by Leonardo Herrera (Standard support level)
Joined: 02/14/2011
Posts: 66

Quote
There are two methods in SBXMLUtils unit:
function GetTextFromXMLElement(const Element: TElXMLDOMElement): XMLString;
function GetStrictTextFromXMLElement(const Element: TElXMLDOMElement): XMLString;
that will return text from the selected element.
For example:
< body>Te<br />xt</ body>
the first method will return "Text", and a second will throw exception as it allows only text and entities under the selected element.


Great! 'GetTextFromXMLElement()' seems to be what I'm after.

Quote
For example to select Signature element you can use a following code:


Yep, I did that except that I didn't checked for 'NodeType = ntElement'.
Quote
I think you are talking about InnerText method, it is not supported at the moment, only InnerXML property is supported. We will add it in the next build.

That'll be great.
Quote
You are invoking GetElementsByTagName method from DocumentElement? Then it could be a problem. As GetElementsByTagName method search for direct childs only.
You can use SelectNodes method, or use FindElementByName method from SBXMLUtils that will search for first occurrences of the element.
For example:
Code

El : TElXMLDOMElement := SBXMLUtils.FindElementByName(Doc.DocumentElement, 'SEED', ''); // last parameter is NamespaceURI


I think this will do it. I'll try again later.

Many thanks for your quick response!

Reply

Statistics

Topic viewed 1343 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!