Malformed XML parser
lazarus / 38-Networking and Web Programming
----------------------------------------------------------------------
gicla · 2018-02-06 22:57
Help me please! I surfed the web for days but I could not find any
help or code examples about how to parse a so called "malformed" XML
file.
I have to read nodes in a log file in which there are messages XML
style but without root node.
This is an example:
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i 000241230
0002412300ApprovedCurrently I'm using:
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i
ReadXMLFile(Doc, fs);ParsingNodes :=
Doc.GetElementsByTagName('Request');But it's working only if I add
root element to the log file before to open it.
Any help will be appreciated.
----------------------------------------------------------------------
molly · 2018-02-07 00:10
Quote from: gicla on February 06, 2018, 11:57:50 pmBut it's working
only if I add root element to the log file before to open it.
You would still have to add the root-node manually because XML will
still need to be valid
Here is another way to accomplish that:
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i RootNode
:= Doc.CreateElement('root'); Doc.AppendChild(RootNode);
ReadXMLFragment(RootNode, 'data.xml'); ParsingNodes :=
Doc.GetElementsByTagName('Request');
----------------------------------------------------------------------
gicla · 2018-02-07 10:11
Thanks molly,
your hint it's perfectly working with the xml in my previous example.
Problem now is that the real xml I'm going to read is slightly
different, it has a declaration and looks like the following:
Code: XML [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i 2018-01-30
10:30:43,862 INFO [Transaction-1] [REQUEST ] message:[000241<
/Seq>230Not
Approved]2018-01-30 10:30:43,862 INFO
[Transaction-3] [REQUEST ] message:[00024123<
/Type>00Approved]
When trying to open it, the command ReadXMLFragment generate the
following error: "XML declaration is not allowed here".
Is there any parameter I can set in order for the ReadXMLFragment
command to ignore the XML declaration?
This is the current piece of code:
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i var I:
Integer; fs: TFileStream; PassNode: TDOMNode; Doc: TXMLDocument;
ParsingNodes: TDOMNodeList; begin if OpenDialog1.Execute then
begin fs := nil; fs :=
TFileStream.Create(Utf8ToAnsi(OpenDialog1.FileName), fmOpenRead or
fmShareDenyNone); Doc := TXMLDocument.Create; PassNode :=
Doc.CreateElement('root'); Doc.AppendChild(PassNode);
ReadXMLFragment(PassNode, fs); <-- LINE
GENERATING THE ERROR ParsingNodes :=
Doc.GetElementsByTagName('TransactionResponse'); //seleziona solo
responses for I := 0 to doc.DocumentElement.GetChildCount - 1
do begin // ... anything I want to do with the XML
... end; end;end;
Thanks in advance!
----------------------------------------------------------------------
Cyrax · 2018-02-07 19:08
Quote from: gicla on February 07, 2018, 11:11:07 amThanks molly,
your hint it's perfectly working with the xml in my previous example.
Problem now is that the real xml I'm going to read is slightly
different, it has a declaration and looks like the following:
Code: XML [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i 2018-01-30
10:30:43,862 INFO [Transaction-1] [REQUEST ] message:[000241<
/Seq>230Not
Approved]2018-01-30 10:30:43,862 INFO
[Transaction-3] [REQUEST ] message:[00024123<
/Type>00Approved]
When trying to open it, the command ReadXMLFragment generate the
following error: "XML declaration is not allowed here".
Is there any parameter I can set in order for the ReadXMLFragment
command to ignore the XML declaration?
You need to learn and use regular expression to extract the xml
portion from the data.
http://wiki.freepascal.org/Regexpr
Quote from: gicla on February 07, 2018, 11:11:07 amThis is the current
piece of code:
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i var I:
Integer; fs: TFileStream; PassNode: TDOMNode; Doc: TXMLDocument;
ParsingNodes: TDOMNodeList; begin if OpenDialog1.Execute then
begin fs := nil; fs :=
TFileStream.Create(Utf8ToAnsi(OpenDialog1.FileName), fmOpenRead or
fmShareDenyNone); Doc := TXMLDocument.Create; PassNode :=
Doc.CreateElement('root'); Doc.AppendChild(PassNode);
ReadXMLFragment(PassNode, fs); <-- LINE
GENERATING THE ERROR ParsingNodes :=
Doc.GetElementsByTagName('TransactionResponse'); //seleziona solo
responses for I := 0 to doc.DocumentElement.GetChildCount - 1
do begin // ... anything I want to do with the XML
... end; end;end;
Thanks in advance!
----------------------------------------------------------------------
molly · 2018-02-07 22:38
Quote from: gicla on February 07, 2018, 11:11:07 amProblem now is that
the real xml I'm going to read is slightly different...
Indeed, and alas, in that case the readXMLfragment is also not able to
help you out there.
If it was me, i would take a moment to think on what it is exactly
that you wish to accomplish as there could be several approaches.
First, it seems to me that your file is a log file. Each entry in that
log is situated on a single line. Part of that line contains xml.
What is it that you wish to accomplish with the data stored in the xml
part (and what of the other information for that matter) ?
Is your goal to end up with a single xml document that has each entry
listed, so that you are able to query the xml document for those data
that you need ? Or is it that the only reason to use xml parsing is
because your data is stored in xml format, and that you do not care
about that at all as long as you are able to extract the parts that
you are interested in ?
In case the former, you could perhaps use a stringlist for line
parsing, use extractword (and related function) to break apart the
line and store that into an xml document. In that case the xml tags
would have to be removed/skipped/ignored/replaced.
In case the latter then using a regular expressions might perhaps be
more helpful, as suggested by user Cyrax (you could use regex for the
former as well, but nothing a simple search and replace or extractword
couldn't fix for you).
Secondly, there is use of non compliant xml. You could perhaps solve
that with using a on the fly xml parser (react to events) (perhaps
better known as sax), but you have to take into account that in the
end using a sax parser could perhaps not solve the reading/parsing for
you either.
Another possible approach could be to use benibela's internet tools
I'm too inexperienced with xml (and mentioned approaches) to be able
to give you a better advice atm. I was unable to solve it in a more
easier manner, but perhaps other readers have an idea or two.
----------------------------------------------------------------------
gicla · 2018-02-07 23:50
Thanks a lot molly for your very detailed comments. I appreciated.
At the end, if no better solution from other readers, I guess I will
read the log file, search for and extract xml portions and store them
in an array.
Then I will validate every xml message one at a time picking them from
the array.
I'll update the post if succesful.