version 0.3.0
[fms.git] / include / ifmsxmldocument.h
1 #ifndef _ifmsxmldocument_\r
2 #define _ifmsxmldocument_\r
3 \r
4 #include <Poco/DOM/Document.h>\r
5 #include <Poco/DOM/Element.h>\r
6 #include <Poco/DOM/Text.h>\r
7 #include <Poco/DOM/CDATASection.h>\r
8 #include <Poco/DOM/DOMParser.h>\r
9 #include <Poco/DOM/DOMWriter.h>\r
10 #include <Poco/XML/XMLWriter.h>\r
11 #include <Poco/AutoPtr.h>\r
12 \r
13 #include "stringfunctions.h"\r
14 \r
15 #include <string>\r
16 \r
17 #ifdef XMEM\r
18         #include <xmem.h>\r
19 #endif\r
20 \r
21 /**\r
22         \brief Interface for objects that represent an XML document\r
23 */\r
24 class IFMSXMLDocument\r
25 {\r
26 public:\r
27         \r
28         /**\r
29                 \brief Returns xml document represented by this object\r
30                 \r
31                 \return xml document\r
32         */\r
33         virtual std::string GetXML()=0;\r
34         \r
35         /**\r
36                 \brief Parses an xml document into this object\r
37                 \r
38                 \return true if the document was parsed successfully, false if it was not\r
39         */\r
40         virtual const bool ParseXML(const std::string &xml)=0;\r
41 \r
42 protected:\r
43         /**\r
44                 Poco doesn't like CDATA with whitespace outside the tags\r
45                 This will remove the whitespace from around CDATA tags\r
46         */\r
47         virtual const std::string FixCDATA(const std::string &xmlstr)\r
48         {\r
49                 std::string rstring=xmlstr;\r
50                 std::string::size_type beg1=std::string::npos;\r
51                 std::string::size_type end1=rstring.find("<![CDATA[");\r
52                 std::string::size_type beg2=std::string::npos;\r
53                 std::string::size_type end2=std::string::npos;\r
54 \r
55                 while(end1!=std::string::npos)\r
56                 {\r
57                         beg1=rstring.rfind(">",end1);\r
58                         if(beg1!=end1-1)\r
59                         {\r
60                                 rstring.erase(beg1+1,end1-(beg1+1));\r
61                         }\r
62 \r
63                         beg2=rstring.find("]]>",end1);\r
64                         if(beg2!=std::string::npos)\r
65                         {\r
66                                 end2=rstring.find("<",beg2);\r
67                                 if(end2!=std::string::npos)\r
68                                 {\r
69                                         rstring.erase(beg2+3,end2-(beg2+3));\r
70                                 }\r
71                         }\r
72 \r
73                         end1=rstring.find("<![CDATA[",end1+1);\r
74                 }\r
75                 return rstring;\r
76         }\r
77         /**\r
78                 \brief Creates and returns an element with a boolean value\r
79         */\r
80         virtual Poco::XML::Element *XMLCreateBooleanElement(Poco::XML::Document *doc, const std::string &name, const bool value)\r
81         {\r
82                 if(doc)\r
83                 {\r
84                         Poco::XML::Text *txt=doc->createTextNode(value ? "true" : "false");\r
85                         Poco::XML::Element *el=doc->createElement(name);\r
86                         el->appendChild(txt);\r
87                         return el;\r
88                 }\r
89                 else\r
90                 {\r
91                         return NULL;\r
92                 }\r
93         }\r
94 \r
95         /**\r
96                 \brief Creates and returns an element with a CDATA value\r
97         */\r
98         virtual Poco::XML::Element *XMLCreateCDATAElement(Poco::XML::Document *doc, const std::string &name, const std::string &data)\r
99         {\r
100                 if(doc)\r
101                 {\r
102                         // Poco XML won't break up CDATA sections correctly when assigned a string with the \r
103                         // end tag is present.  However, it will parse it correctly, so we will manually break the\r
104                         // CDATA into separate parts\r
105                         Poco::XML::CDATASection *sec=doc->createCDATASection(StringFunctions::Replace(data,"]]>","]]]><![CDATA[]>"));\r
106                         Poco::XML::Element *el=doc->createElement(name);\r
107                         el->appendChild(sec);\r
108                         return el;\r
109                 }\r
110                 else\r
111                 {\r
112                         return NULL;\r
113                 }\r
114         }\r
115 \r
116         /**\r
117                 \brief Creates and returns a text element\r
118         */\r
119         virtual Poco::XML::Element *XMLCreateTextElement(Poco::XML::Document *doc, const std::string &name, const std::string &data)\r
120         {\r
121                 if(doc)\r
122                 {\r
123                         Poco::XML::Text *txt=doc->createTextNode(data);\r
124                         Poco::XML::Element *el=doc->createElement(name);\r
125                         el->appendChild(txt);\r
126                         return el;\r
127                 }\r
128                 else\r
129                 {\r
130                         return NULL;\r
131                 }\r
132         }\r
133 \r
134         virtual Poco::XML::Element *XMLCreateTextElement(Poco::XML::Document *doc, const std::string &name, const long data)\r
135         {\r
136                 if(doc)\r
137                 {\r
138                         std::string datastr;\r
139                         StringFunctions::Convert(data,datastr);\r
140                         return XMLCreateTextElement(doc,name,datastr);\r
141                 }\r
142                 else\r
143                 {\r
144                         return NULL;\r
145                 }\r
146         }\r
147 \r
148         virtual const bool XMLGetBooleanElement(Poco::XML::Element *parent, const std::string &name)\r
149         {\r
150                 Poco::XML::Element *el=XMLGetFirstChild(parent,name);\r
151                 if(el && el->firstChild())\r
152                 {\r
153                         if(el->firstChild()->getNodeValue()=="true")\r
154                         {\r
155                                 return true;\r
156                         }\r
157                         else\r
158                         {\r
159                                 return false;\r
160                         }\r
161                 }\r
162                 return false;\r
163         }\r
164 \r
165         virtual Poco::XML::Element *XMLGetFirstChild(Poco::XML::Node *parent, const std::string &name)\r
166         {\r
167                 if(parent)\r
168                 {\r
169                         Poco::XML::Node *child=parent->firstChild();\r
170                         while(child && child->nodeName()!=name)\r
171                         {\r
172                                 child=child->nextSibling();\r
173                         }\r
174                         return static_cast<Poco::XML::Element *>(child);\r
175                 }\r
176                 else\r
177                 {\r
178                         return NULL;\r
179                 }\r
180         }\r
181 \r
182         virtual Poco::XML::Element *XMLGetNextSibling(Poco::XML::Node *node, const std::string &name)\r
183         {\r
184                 if(node)\r
185                 {\r
186                         Poco::XML::Node *next=node->nextSibling();\r
187                         while(next && next->nodeName()!=name)\r
188                         {\r
189                                 next=next->nextSibling();\r
190                         }\r
191                         return static_cast<Poco::XML::Element *>(next);\r
192                 }\r
193                 else\r
194                 {\r
195                         return NULL;\r
196                 }\r
197         }\r
198 \r
199         const std::string SanitizeSingleString(const std::string &text)\r
200         {\r
201                 std::string returntext=text;\r
202                 // remove bogus chars from text string\r
203                 for(char i=1; i<32; i++)\r
204                 {\r
205                         returntext=StringFunctions::Replace(returntext,std::string(1,i),"");\r
206                 }\r
207                 return returntext;\r
208         }\r
209 \r
210         const std::string GenerateXML(Poco::XML::Document *doc)\r
211         {\r
212                 std::ostringstream str;\r
213                 if(doc)\r
214                 {\r
215                         Poco::XML::DOMWriter dr;\r
216                         dr.setOptions(Poco::XML::XMLWriter::WRITE_XML_DECLARATION | Poco::XML::XMLWriter::PRETTY_PRINT);\r
217                         dr.setNewLine(Poco::XML::XMLWriter::NEWLINE_CRLF);\r
218                         dr.writeNode(str,doc);\r
219                 }\r
220                 return str.str();\r
221         }\r
222         \r
223 };\r
224 \r
225 #endif  // _ifmsxmldocument_\r