version 0.3.31
[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::AutoPtr<Poco::XML::Element> XMLCreateBooleanElement(Poco::AutoPtr<Poco::XML::Document> doc, const std::string &name, const bool value)\r
81         {\r
82                 if(doc)\r
83                 {\r
84                         Poco::AutoPtr<Poco::XML::Text> txt=doc->createTextNode(value ? "true" : "false");\r
85                         Poco::AutoPtr<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::AutoPtr<Poco::XML::Element> XMLCreateCDATAElement(Poco::AutoPtr<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::AutoPtr<Poco::XML::CDATASection> sec=doc->createCDATASection(StringFunctions::Replace(data,"]]>","]]]><![CDATA[]>"));\r
106                         Poco::AutoPtr<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::AutoPtr<Poco::XML::Element> XMLCreateTextElement(Poco::AutoPtr<Poco::XML::Document> doc, const std::string &name, const std::string &data)\r
120         {\r
121                 if(doc)\r
122                 {\r
123                         Poco::AutoPtr<Poco::XML::Text> txt=doc->createTextNode(data);\r
124                         Poco::AutoPtr<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::AutoPtr<Poco::XML::Element> XMLCreateTextElement(Poco::AutoPtr<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 child.cast<Poco::XML::Element>();\r
175                         return static_cast<Poco::XML::Element *>(child);\r
176                 }\r
177                 else\r
178                 {\r
179                         return NULL;\r
180                 }\r
181         }\r
182 \r
183         virtual Poco::XML::Element *XMLGetNextSibling(Poco::XML::Node *node, const std::string &name)\r
184         {\r
185                 if(node)\r
186                 {\r
187                         Poco::XML::Node *next=node->nextSibling();\r
188                         while(next && next->nodeName()!=name)\r
189                         {\r
190                                 next=next->nextSibling();\r
191                         }\r
192                         //return next.cast<Poco::XML::Element>();\r
193                         return static_cast<Poco::XML::Element *>(next);\r
194                 }\r
195                 else\r
196                 {\r
197                         return NULL;\r
198                 }\r
199         }\r
200 \r
201         const std::string SanitizeSingleString(const std::string &text)\r
202         {\r
203                 std::string returntext=text;\r
204                 // remove bogus chars from text string\r
205                 for(char i=1; i<32; i++)\r
206                 {\r
207                         returntext=StringFunctions::Replace(returntext,std::string(1,i),"");\r
208                 }\r
209                 return returntext;\r
210         }\r
211 \r
212         const std::string GenerateXML(Poco::AutoPtr<Poco::XML::Document> doc, const bool prettyprint=true)\r
213         {\r
214                 std::ostringstream str;\r
215                 if(doc)\r
216                 {\r
217                         Poco::XML::DOMWriter dr;\r
218                         if(prettyprint==true)\r
219                         {\r
220                                 dr.setOptions(Poco::XML::XMLWriter::WRITE_XML_DECLARATION | Poco::XML::XMLWriter::PRETTY_PRINT);\r
221                         }\r
222                         else\r
223                         {\r
224                                 dr.setOptions(Poco::XML::XMLWriter::WRITE_XML_DECLARATION);\r
225                         }\r
226                         dr.setNewLine(Poco::XML::XMLWriter::NEWLINE_CRLF);\r
227                         dr.writeNode(str,doc);\r
228                 }\r
229                 return str.str();\r
230         }\r
231         \r
232 };\r
233 \r
234 #endif  // _ifmsxmldocument_\r