|
Hi to Everyone,
First Thank a lot for this code. Now I am a beginner in this XML parsing area. I want to parse an XML file so what i need to do ?
I am looking forward from you.
Thanks & Regards,
Rajiv
|
|
|
|
|
Hi,
First of all, Thanks for your posting.
I hope to use your code for my own code.
Now, I wonder about your code's license, whether it takes "CPOL" or not.
Waiting for your reply.
Thank you.
|
|
|
|
|
This program is not a Standard C++ program because of the non standard libraries it uses.
Anyway it is really easy to make it use the STL only.
I did it and it seems to work (using gcc).
I cannot find a way to attach a file from here, so if someone should be interested, just let me know and I will send you the code directly.
--> pietromele@yahoo.com
|
|
|
|
|
I needed to modify something to compile (using Code::Blocks) with mingw. First of all, I couldn't use atlbase.h I defined only windows.h. Second, I had to change this kind of lines in XMLParser.h:
string::iterator start = _buffer + offset;
for this:
string::iterator start = ((string)_buffer).begin() + offset;
That's all. Thanks for your code
|
|
|
|
|
has anyone tried to make this code run on vc2005?
I get alot of cannot convert type string to iterator etc etc... I finally got around the problems
by not using this code, but I find myself wondering why the new compiler is so string on converting pointers to iterators.
Bryan
|
|
|
|
|
Hi Bryan,
I have the same problem, whenever I want to compile the project under VS2005 I get lots can't convert error, could you say what did u do or post your code here please.
Regards,
|
|
|
|
|
Perhaps this has been talked a lot but I can not stop my self from writing this.
One of the reasons of XML is connecting platforms, apps through text encoded messages, to achieve this you need compliance. Implementing a fully (95%-98%) compliant XML parser is really hard. Usually an average Dev can get to 80% pretty quickly and the experienced can get to %90. The rest is all egde cases and getting them right requires extensive testing suites to ensure compat between different platforms. I know this by experience. There are quite a few xml parser implementations out there. Users are usually best served when the xml parser implementations are recognized by the W3C Recommendations. Other implementations can not go any further than academic studies as the cost of them making interop with the rest of the world sky rockets as dev's are trying to achieve %95 compat.
|
|
|
|
|
If I have xml scheme like below and I like to get the attribute value such as 22805, SA287430035 or ENV_LAN_1. How would I do it? thank in advance.
--------------------------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<LOADBOX>
<row BoxID="22805" BoxSerialNumber="SA287430035" BoxTest="ENV_LAN_1">
<row BoxID="77688" BoxSerialNumber="SA287460015" BoxTest="ENV_LAN_5">
<row BoxID="15141" BoxSerialNumber="HK184700609" BoxTest="ENV1">
</LOADBOX>
|
|
|
|
|
Me too require solution for the same problem. Can anyone help!!
I use java.
|
|
|
|
|
thanks for the great XML tools, they are very easy to use.
I would like to have a table represented in XML but this implementation of the parser doesn't handle multiple entries of the same name, for example:
<HOST>
<NAME>cod</NAME>
<DNSNAME>cod.somecorp.com</DNSNAME>
<NIC>
<MAC>0040f4612820</MAC>
<IP>192.168.172.54</IP>
<IP>192.168.173.54</IP>
</NIC>
</HOST>
<HOST>
<NAME>drum</NAME>
<DNSNAME>drum.somecorp.com</DNSNAME>
<NIC>
<IP>192.168.172.47</IP>
</NIC>
</HOST>
in this example the <HOST> and <IP> tags both have multiple entries. the XMLDialog displays the host cod for both entries, and only 1 IP address, it would be nice to be able to address these in the read/write methods like:
"HOST[0]:NIC:IP[1]","192.168.173.54"
--Ben Burnett
|
|
|
|
|
I found the same problem, and believe it is related to this code in XmlStream.cpp:
// if new parse cur position is in the last parser
// last tag position we are done with the node
char * curPos = parserNode.getCurPos();
char * lastCurPos = parser.getLastTagPos();
if ( curPos >= lastCurPos )
{
break;
}
This code seems to assume that if you hit the end of a node at a certain level of XML heirarchy, you also must be done with that entire heirarchical level altogether. (When first </HOST> is hit, there won't be any more <HOST> entries to follow).
I simply removed that code and allowed the above parser.parse() method to do what it does, and that seemed to fix the problem.
I don't quite know if this will introduce other issues, though.
- MikeG
-- modified at 23:47 Friday 14th October, 2005
|
|
|
|
|
I found a bug...
when nearby nodes have the same name, the next node will be ignore
ex:
<br />
<Node id="n0"><br />
<Node id="n1"><br />
<Element id="e1"/> <br />
</Node><br />
</Node><br />
will only found the first node "n0"
|
|
|
|
|
sorry...
example code here...
<Node id="n0">
<Node id="n1">
<Element id="e1"/>
</Node>
</Node>
|
|
|
|
|
in generell i find my way of prettyprinting a bit more easier to read:
stringstream strm;
strm
<< "<Contacts>" << endl
<< "<Contact/>" << endl
<< initContact( "Joe Blow", 100 )
<< initContact( "Mary Jane", 400, true, true )
<< "</Contacts>" << endl
;
another question:
even its a examples, i find it better to return some string, which is streamed, instead to write directly to the stream.
this method safes an unneccesary argument,
can be reused easier,
ok only disadvantage: creating temporarily a string for returning. but i think its ok, because the entries are all pretty small...
---------------------
string initContact ( LPCTSTR cname, long id,
bool hasAttributes = false,
bool showToDo = false )
{
stringstream strm;
if ( hasAttributes )
strm << "<Contact language=\"english\" hasEmail=\"false\">" << endl;
else
strm << "<Contact>" << endl;
strm
<< "<name>" << cname << "</name>" << endl
<< "<id>" << id << "</id>" << endl
;
if ( showToDo )
{
strm
<< "<ToDo>" << endl
<< "<Item></Item>" << endl
<< "<Item/>" << endl
<< "<Item>Call</Item>" << endl
<< "<Item>Say Hello</Item>" << endl
<< "<Item>Take Notes</Item>" << endl
<< "<Item>HangUp</Item>" << endl
<< "</ToDo>" << endl
;
}
strm << "</Contact>" << endl;
return( strm.str() );
}
|
|
|
|
|
to be valid XML u should enclose all attribs with ":
strm << "<Contact language=\"english\" hasEmail=\"false\">" << endl;
cu george.
|
|
|
|
|
Parser will 'kick out' of a parent node when a subnode is a null node entry:
<Skin Name="CMX">
<Information>
<Author>John Doe</Author>
<Copyright>2003</Copyright>
</Information>
<Resource Type="Font" Name="SmallFont" File="Font10.fnt"/>
<Resource Type="Font" Name="NormalFont" File="Font16.fnt"/>
<Resource Type="Font" Name="GameText" File="GameText.fnt"/>
<Resource Type="Image" Name="Title" File="TitleScr.jpg"/>
<Resource Type="Image" Name="MenuBack" File="MenuScr.jpg"/>
</Skin>
This will kick out on the first "Resource" node.
The problem lies in xmlparser.h, the routine 'parse()':
// if null tag no data or last tag
if ( hasNullTag() )
{
// update cur position
_current = _firstTagEnd + idTagRightLength;
// done so show success
return true;
}
needs to change to:
// if null tag no data or last tag
if ( hasNullTag() )
{
// update cur position
_current = _firstTagEnd + idTagRightLength;
_lastTagStart = _current;
_lastTagEnd = _current;
// done so show success
return true;
}
and the parser will work properly.
|
|
|
|
|
Strange...
The fix does work, after a fashion, but there seems to be no rhyme or reason as to whether a null tag is considered a node or an element.
I've modified my code not to worry about it, but if anybody can figure this out, I'd greatly appreciate it.
|
|
|
|
|
I've got an xml file with standard header and comments like this:
<?xml version="1.0" ?>
<!-- Ok ? -->
<!-- Ok -->
<Tag currentTag="0">
...
The parser fails reading the xml file because of the header and comments.
Well, good job anyway. I'm working on the fix, I'll post it when done.
Yarp
http://www.senosoft.com/
|
|
|
|
|
So here'a partial fix:
bool hasNullTag ()
{
char * firstTagBegin = _buffer + _firstTagStart;
char * firstTagEnd = _buffer + _firstTagEnd - 1;
if (( *firstTagBegin == '<' && *(firstTagBegin+1) == '?' ) ||
( *firstTagBegin == '<' && *(firstTagBegin+1) == '!' ) ||
( *firstTagEnd == '/' && *(firstTagEnd+1) == '>' ))
return true;
else
return false;
}
Not perfect since the XmlNotify class is still called but this is easy to fix too:
Each time a _subscriber is called just test if the parsed name isn't "?" or "!". I recall that the _subscriber is called by XmlStream to notify the caller for the xml parsing result.
Yarp
http://www.senosoft.com/
|
|
|
|
|
Is there a way to repetitively search the XML stream for any nodes containing specific elements, by value? This search would return the entire nodes contents.
David Frame
|
|
|
|
|
I would like to know if somebody has developped this issue.
Thanks.
|
|
|
|
|
File: XmlParser.h
Method: bool parseAttributes ()
Change lines:
if ( hasNullTag() )
_attrEnd -= -1;
To these one:
if ( hasNullTag() )
_attrEnd -= 1;
Apllied to attributes in null-tag nodes.
|
|
|
|
|
is there a way to force a notify callback when the end of a node is reached? this would make it much easier to handle nested nodes.
-c
------------------------------
Smaller Animals Software, Inc.
http://www.smalleranimals.com
|
|
|
|
|
I used extra parser's member _level for foundNode/foundElement notifications like those:
// xml notify methods
virtual void foundNode( string & name, string & attributes, int level );
virtual void foundElement( string & name, string & value, string & attributes, int level );
It is based on the fact that each parser instance is created for each node.
xmlSteam.cpp:
XmlParser parserNode(parser.getLevel());
if ( !parseNodes(parserNode,valueBuffer,valueLength) )
return false;
xmlParser.h:
XmlParser (int parentLevel) : _strParse()
{
clear();
// parser level, starts from 0 in default constructor
_level = parentLevel + 1;
}
Gennady Khokhorin
Software Developer
|
|
|
|
|
Can you please send me the whole code. thanks
|
|
|
|