OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimXmlNode.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: Oscar Kramer <okramer@imagelinks.com> (ossim port by D. Burken)
6 //
7 // Description:
8 //
9 // Contains definition of class ossimXmlNode.
10 //
11 //*****************************************************************************
12 // $Id: ossimXmlNode.cpp 20747 2012-04-18 15:24:12Z gpotts $
13 
14 #include <iostream>
19 #include <ossim/base/ossimTrace.h>
20 
21 namespace {// Anonymous namespace
22  // Constants
23  const char XPATH_DELIM ('/');
24  ossimRefPtr<ossimXmlNode> const nullNode(0);
25 
26  // Globals
27  ossimTrace traceDebug("ossimXmlNode:debug");
28 }// Anonymous namespace
29 
31 
32 static std::istream& xmlskipws(std::istream& in)
33 {
34  int c = in.peek();
35  while( !in.fail() &&
36  (( (c== ' ') || (c == '\t') || (c == '\n')|| (c == '\r') || (c<0x20) || (c>=0x7f) ))
37  )
38  {
39  in.ignore(1);
40  c = in.peek();
41  }
42 
43  return in;
44 }
45 
47 :
48 theParentNode (parent),
49 theCDataFlag(false)
50 {
51  read(xml_stream);
52 }
53 
55 :theParentNode(0),
56 theCDataFlag(false)
57 {
58 }
59 
61 :theTag(src.theTag),
62 theParentNode(0),
63 theText(src.theText),
64 theCDataFlag(src.theCDataFlag)
65 {
66  ossim_uint32 idx = 0;
67  for(idx = 0; idx < src.theChildNodes.size();++idx)
68  {
69  theChildNodes.push_back((ossimXmlNode*)(src.theChildNodes[idx]->dup()));
70  }
71  for(idx = 0; idx < src.theAttributes.size();++idx)
72  {
73  theAttributes.push_back((ossimXmlAttribute*)(src.theAttributes[idx]->dup()));
74  }
75 }
76 
78 {
79 }
80 
82 {
83  ossim_uint32 idx = 0;
84  for(idx = 0; idx<theAttributes.size();++idx)
85  {
86  result.push_back((ossimXmlAttribute*)theAttributes[idx]->dup());
87  }
88 
89 }
90 
92 {
93  ossim_uint32 idx = 0;
94  for(idx = 0; idx<theChildNodes.size();++idx)
95  {
96  result.push_back((ossimXmlNode*)theChildNodes[idx]->dup());
97  }
98 }
99 
101 {
102  theParentNode = parent;
103 }
104 
106 {
107  char c;
108  while(!in.fail())
109  {
110  c = in.get();
111  if(c == '-')
112  {
113  if(in.peek() == '-')
114  {
115  in.ignore();
116  if(in.peek() == '>')
117  {
118  in.ignore();
119  return;
120  }
121  }
122  }
123  }
124 }
125 
127 {
128  if(traceDebug())
129  {
131  << "ossimXmlNode::read: entered ......\n";
132  }
133  char c;
134  xmlskipws(in);
135  if(in.fail())
136  {
137  if(traceDebug())
138  {
140  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
141  }
142  return false;
143  }
144  if(in.peek() == '<')
145  {
146  in.ignore(1);
147  }
148  if(in.fail())
149  {
150  if(traceDebug())
151  {
153  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
154  }
155  return false;
156  }
157 
158  ossimString endTag;
159 
160  if(!readTag(in, theTag))
161  {
162  if(traceDebug())
163  {
165  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
166  }
167  return false;
168  }
169  if(traceDebug())
170  {
171  ossimNotify(ossimNotifyLevel_DEBUG) << "theTag = " << theTag << "\n";
172  }
173 
174  if((!in.fail())&&readEndTag(in, endTag))
175  {
176  if((endTag == "")||
177  (endTag == theTag))
178  {
179  if(traceDebug())
180  {
182  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
183  }
184  return true;
185  }
186  else
187  {
188  setErrorStatus();
189  if(traceDebug())
190  {
192  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
193  }
194  return false;
195  }
196  }
197  // now parse attributes
199  while(attribute->read(in))
200  {
201  theAttributes.push_back(new ossimXmlAttribute(*attribute));
202  }
203  // skip white space characters
204  //
205  xmlskipws(in);
206 
207  if(!in.fail()&&readEndTag(in, endTag))
208  {
209  if((endTag == "")||
210  (endTag == theTag))
211  {
212  if(traceDebug())
213  {
215  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
216  }
217  return true;
218  }
219  else
220  {
221  setErrorStatus();
222  if(traceDebug())
223  {
225  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
226  }
227  return false;
228  }
229  }
230  c = in.peek();
231  // make sure the attribute is closed
232  //
233  if(c != '>')
234  {
235  setErrorStatus();
236  if(traceDebug())
237  {
239  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
240  }
241  return false;
242  }
243 
244  in.ignore(1);
245  c = in.peek();
246 
247  // now do the text portion
248  if(!readTextContent(in))
249  {
250  if(traceDebug())
251  {
253  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
254  }
255  return false;
256  }
257  xmlskipws(in);
258  c = in.peek();
259 
260  if(c != '<')
261  {
262  setErrorStatus();
263  if(traceDebug())
264  {
266  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
267  }
268  return false;
269  }
270  in.ignore(1);
271  if(readEndTag(in, endTag))
272  {
273  if((endTag == "")||
274  (endTag == theTag))
275  {
276  if(traceDebug())
277  {
279  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
280  }
281  return true;
282  }
283  else
284  {
285  setErrorStatus();
286  if(traceDebug())
287  {
289  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
290  }
291  return false;
292  }
293  }
294  c = in.peek();
295 
296  //---
297  // now if it's not an endtag then it must be a tag starting the new child
298  // node
299  //---
300  ossimRefPtr<ossimXmlNode> childNode;
301  do
302  {
303  childNode = new ossimXmlNode;
304  childNode->setParent(this);
305  if(childNode->read(in))
306  {
307  theChildNodes.push_back(childNode);
308  }
309  else
310  {
311  setErrorStatus();
312  if(traceDebug())
313  {
315  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
316  }
317  return false;
318  }
319  xmlskipws(in);
320 
321  c = in.peek();
322  if(c != '<')
323  {
324  setErrorStatus();
325  if(traceDebug())
326  {
328  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
329  }
330  return false;
331  }
332  in.ignore(1);
333  if(readEndTag(in, endTag))
334  {
335  if((endTag == "")||
336  (endTag == theTag))
337  {
338  if(traceDebug())
339  {
341  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
342  }
343  return true;
344  }
345  else
346  {
347  setErrorStatus();
348  if(traceDebug())
349  {
351  << "ossimXmlNode::read: leaving ......\n"<<__LINE__ << "\n";
352  }
353  return false;
354  }
355  }
356  }while( !in.fail() );
357 
358  if(traceDebug())
359  {
361  << "ossimXmlNode::read: leaving ......\n";
362  }
363  return true;
364 }
365 
366 
368  ossimXmlNode::ChildListType& result)const
369 {
370  //***
371  // Scan for trivial result (no children owned):
372  //***
373  if (theChildNodes.empty())
374  return;
375 
376  if (xpath.empty())
377  return;
378 
379  //---
380  // First verify that this is not an absolute path:
381  //---
382  if (xpath[static_cast<std::string::size_type>(0)] == XPATH_DELIM)
383  {
384  if(traceDebug())
385  {
387  << "WARNING: ossimXmlNode::findChildNodes\n"
388  << "Only relative XPaths can be searched from a node. "
389  << "Returning null list...\n";
390  }
391  return;
392  }
393 
394  //***
395  // Read the desired tag from the relative xpath
396  //***
397  const std::string::size_type delim_pos = xpath.find(XPATH_DELIM);
398  // TODO: need string_view
399  const ossimString desired_tag = xpath.substr(0,delim_pos);
400 
401  //***
402  // Loop over all child nodes for match:
403  //***
404  ossimXmlNode::ChildListType::const_iterator child_iter = theChildNodes.begin();
405  ossimXmlNode::ChildListType::const_iterator child_end = theChildNodes.end();
406 
407 
408  // No XPATH_DELIM character found, or XPATH_DELIM at the end of xpath
409  if (delim_pos==std::string::npos || delim_pos == xpath.size()-1)
410  {
411  for ( ; child_iter != child_end ; ++ child_iter)
412  {
413  if ((*child_iter)->getTag() == desired_tag)
414  //***
415  // This was the final target node, simply append to the result:
416  //***
417  result.push_back(*child_iter);
418  }
419  }
420  else
421  {
422  const ossimString sub_xpath = xpath.substr(delim_pos+1, std::string::npos);
423  for ( ; child_iter != child_end ; ++ child_iter)
424  {
425  if ((*child_iter)->getTag() == desired_tag)
426  //***
427  // This match identifies a possible tree to search given the
428  // remaining xpath (sub_xpath). Query this child node to search
429  // its tree for the remaining xpath:
430  //***
431  (*child_iter)->findChildNodes(sub_xpath, result);
432  }
433  }
434 }
435 
437 {
438  if(theChildNodes.size() < 1) return nullNode;
439  if (xpath.empty())
440  return nullNode;
441 
442  //
443  // First verify that this is not an absolute path:
444  //
445  if (xpath[static_cast<std::string::size_type>(0)] == XPATH_DELIM)
446  {
447  if(traceDebug())
448  {
450  << "WARNING: ossimXmlNode::findFirstNode\n"
451  << "Only relative XPaths can be searched from a node. "
452  << "Returning null list...\n";
453  }
454  return nullNode;
455  }
456 
457  //
458  // Read the desired tag from the relative xpath
459  //
460  const std::string::size_type delim_pos = xpath.find(XPATH_DELIM);
461  // TODO: need string_view
462  const ossimString desired_tag = xpath.substr(0,delim_pos);
463 
464  //
465  // Loop over all child nodes for match:
466  //
467  ossimXmlNode::ChildListType::const_iterator child_iter = theChildNodes.begin();
468  ossimXmlNode::ChildListType::const_iterator child_end = theChildNodes.end();
469 
470  // No XPATH_DELIM character found, or XPATH_DELIM at the end of xpath
471  if (delim_pos==std::string::npos || delim_pos == xpath.size()-1)
472  {
473  for ( ; child_iter != child_end ; ++ child_iter)
474  {
475  if ((*child_iter)->getTag() == desired_tag)
476  return *child_iter;
477  }
478  }
479  else
480  {
481  const ossimString sub_xpath = xpath.substr(delim_pos+1, std::string::npos);
482  for ( ; child_iter != child_end ; ++ child_iter)
483  {
484  if ((*child_iter)->getTag() == desired_tag)
485  {
486  //
487  // This match identifies a possible tree to search given the
488  // remaining xpath (sub_xpath). Query this child node to search
489  // its tree for the remaining xpath:
490  //
491  const ossimRefPtr<ossimXmlNode>& result = (*child_iter)->findFirstNode(sub_xpath);
492  if (result.get())
493  {
494  return result;
495  }
496  }
497  }
498  }
499 
500  return nullNode;
501 }
502 
504 {
505  if(theChildNodes.size() < 1) return 0;
506  if (xpath.empty())
507  return 0;
508 
509  //
510  // First verify that this is not an absolute path:
511  //
512  if (xpath[static_cast<std::string::size_type>(0)] == XPATH_DELIM)
513  {
514  if(traceDebug())
515  {
517  << "WARNING: ossimXmlNode::findFirstNode\n"
518  << "Only relative XPaths can be searched from a node. "
519  << "Returning null list...\n";
520  }
521  return 0;
522  }
523 
524  //
525  // Read the desired tag from the relative xpath
526  //
527  const std::string::size_type delim_pos = xpath.find(XPATH_DELIM);
528  // TODO: need string_view
529  const ossimString desired_tag = xpath.substr(0,delim_pos);
530 
531  ossimRefPtr<ossimXmlNode> result = 0;
532 
533  //
534  // Loop over all child nodes for match:
535  //
536  ossimXmlNode::ChildListType::iterator child_iter = theChildNodes.begin();
537  ossimXmlNode::ChildListType::iterator child_end = theChildNodes.end();
538 
539  // No XPATH_DELIM character found, or XPATH_DELIM at the end of xpath
540  if (delim_pos==std::string::npos || delim_pos == xpath.size()-1)
541  {
542  for ( ; child_iter != child_end ; ++ child_iter)
543  {
544  if ((*child_iter)->getTag() == desired_tag)
545  return *child_iter;
546  }
547  }
548  else
549  {
550  const ossimString sub_xpath = xpath.substr(delim_pos+1, std::string::npos);
551  for ( ; child_iter != child_end ; ++ child_iter)
552  {
553  if ((*child_iter)->getTag() == desired_tag)
554  {
555  //
556  // This match identifies a possible tree to search given the
557  // remaining xpath (sub_xpath). Query this child node to search
558  // its tree for the remaining xpath:
559  //
560  ossimRefPtr<ossimXmlNode> result = (*child_iter)->findFirstNode(sub_xpath);
561  if (result.get())
562  {
563  return result;
564  }
565  }
566  }
567  }
568 
569  return 0;
570 }
571 
573 {
574  ossim_uint32 idx = 0;
575 
576  for(idx = 0; idx < theAttributes.size();++idx)
577  {
578  if(theAttributes[idx]->getName() == name)
579  {
580  return theAttributes[idx];
581  }
582  }
583 
584  return 0;
585 }
586 
588 {
589  ossim_uint32 idx = 0;
590 
591  for(idx = 0; idx < theAttributes.size();++idx)
592  {
593  if(theAttributes[idx]->getName() == name)
594  {
595  return theAttributes[idx];
596  }
597  }
598 
599  return 0;
600 }
601 
603 {
604  theTag = tag;
605 }
606 
608 {
609  return theParentNode;
610 }
611 
613 {
614  return theParentNode;
615 }
616 
618 {
619  return theChildNodes;
620 }
621 
623 {
624  return theChildNodes;
625 }
626 
628 {
629  return theAttributes;
630 }
631 
633 {
635 
636  if(attribute.valid())
637  {
638  value = attribute->getValue();
639  }
640 
641  return attribute.valid();
642 }
643 
645  const ossimString& relPath)const
646 {
648  if(node.valid())
649  {
650  value = node->getText();
651  }
652 
653  return node.valid();
654 }
655 
656 
658 {
659  theText = text;
660 }
661 
663 {
664  return theCDataFlag;
665 }
666 
668 {
669  theCDataFlag = value;
670 }
671 
672 ostream& operator << (ostream& os, const ossimXmlNode& xml_node)
673 {
674  return operator <<(os, &xml_node);
675 }
676 
677 //**************************************************************************
678 // FRIEND OPERATOR
679 //**************************************************************************
680 ostream& operator << (ostream& os, const ossimXmlNode* xml_node)
681 {
682  //
683  // Determine the indentation level:
684  //
685  ossimString indent ("");
686  const ossimXmlNode* parent = xml_node->theParentNode;
687  while (parent)
688  {
689  indent += " ";
690  parent = parent->theParentNode;
691  }
692 
693  //
694  // Dump the tag opening:
695  //
696  os << "\n" << indent << "<" << xml_node->theTag;
697 
698  //
699  // Dump any attributes:
700  //
701  if (xml_node->theAttributes.size())
702  {
703  ossimXmlNode::AttributeListType::const_iterator attr =
704  xml_node->theAttributes.begin();
705  while (attr != xml_node->theAttributes.end())
706  {
707  os << attr->get();
708  attr++;
709  }
710  }
711 
712  if((xml_node->theChildNodes.size() == 0)&&
713  (xml_node->theText == ""))
714  {
715  os << "/>";
716  }
717  else
718  {
719  os << ">";
720 
721  if(xml_node->cdataFlag())
722  {
723  os << "<![CDATA[" <<xml_node->theText << "]]>";
724  }
725  else
726  {
727  //
728  // Dump any text:
729  //
730  os << xml_node->theText;
731  }
732  //
733  // Dump any child nodes:
734  //
735  if (xml_node->theChildNodes.size())
736  {
737  ossimXmlNode::ChildListType::const_iterator nodes = xml_node->theChildNodes.begin();
738  while (nodes != xml_node->theChildNodes.end())
739  {
740  os << (*nodes).get();
741  nodes++;
742  }
743  os << "\n" << indent;
744  }
745 
746  //
747  // Dump the tag closing:
748  //
749  os << "</" << xml_node->theTag << ">";
750  }
751 
752  return os;
753 }
754 
756 {
757  theAttributes.push_back(attribute.get());
758 }
759 
761  const ossimString& value)
762 {
763  theAttributes.push_back(new ossimXmlAttribute(name, value));
764 }
765 
767  const ossimString& value,
768  bool addIfNotPresentFlag)
769 {
770  bool result = false;
772  if(attribute.valid())
773  {
774  attribute->setValue(value);
775  result = true;
776  }
777  else
778  {
779  if(addIfNotPresentFlag)
780  {
781  addAttribute(name, value);
782  result = true;
783  }
784  }
785 
786  return result;
787 }
788 
790  const ossimString& text)
791 {
792  if (relPath.empty())
793  return 0;
794 
795  //
796  // First verify that this is not an absolute path:
797  //
798  if (relPath[static_cast<std::string::size_type>(0)] == XPATH_DELIM)
799  {
800  if(traceDebug())
801  {
802  ossimNotify(ossimNotifyLevel_WARN) << "WARNING: ossimXmlNode::addNode\n"
803  << "Only relative XPaths can be searched from a node. "
804  << "Returning null list...\n";
805  }
806  return 0;
807  }
808 
809  //
810  // Read the desired tag from the relative xpath
811  //
812  const std::string::size_type delim_pos = relPath.find(XPATH_DELIM);
813  const ossimString desiredTag = relPath.substr(0,delim_pos);
814 
815  ossimRefPtr<ossimXmlNode> node = findFirstNode(desiredTag);
816 
817  if(!node.valid())
818  {
819  // No XPATH_DELIM character found, or XPATH_DELIM at the end of xpath
820  if (delim_pos==std::string::npos || delim_pos == relPath.size()-1)
821  {
822  node = addChildNode(desiredTag, text);
823  }
824  else
825  {
826  node = addChildNode(desiredTag, "");
827  }
828  }
829  if (delim_pos != std::string::npos && delim_pos != relPath.size()-1) // XPATH_DELIM character found!
830  {
831  const ossimString subPath = relPath.substr(delim_pos+1, std::string::npos);
832  return node->addNode(subPath, text);
833  }
834 
835  return node;
836 }
837 
839  const ossimString& text)
840 {
841  ossimRefPtr<ossimXmlNode> result = addNode(relPath, text);
842 
843  result->setText(text);
844 
845  return result;
846 }
847 
849 {
850  if(node->theParentNode)
851  {
852  node->theParentNode->removeChild(node);
853  }
854  node->theParentNode = this;
855  theChildNodes.push_back(node.get());
856 }
857 
859  const ossimString& text)
860 {
862  node->setParent(this);
863  node->theTag = tagName;
864  node->theText = text;
865  theChildNodes.push_back(node);
866 
867  return node;
868 }
869 
871 {
872  ossimXmlNode::ChildListType::iterator iter = theChildNodes.begin();
873  while(iter != theChildNodes.end())
874  {
875 
876  if(node == iter->get())
877  {
878  ossimRefPtr<ossimXmlNode> temp = *iter;
879 
880  theChildNodes.erase(iter);
881 
882  return temp;
883  }
884  ++iter;
885  }
886 
887  return 0;
888 }
889 
891 {
892  ossimXmlNode::ChildListType::iterator iter = theChildNodes.begin();
893  while(iter != theChildNodes.end())
894  {
895  if(tag == iter->get()->theTag)
896  {
897  ossimRefPtr<ossimXmlNode> temp = *iter;
898 
899  theChildNodes.erase(iter);
900 
901  return temp;
902  }
903  ++iter;
904  }
905 
906  return 0;
907 }
909 {
910  ossim_uint32 idx;
911  for(idx = 0; idx < children.size(); ++idx)
912  {
913  addChildNode(children[idx].get());
914  }
915 }
916 
918 {
919  clearChildren();
920  addChildren(children);
921 }
922 
924 {
925  ossim_uint32 idx;
926 
927  for(idx = 0; idx < children.size(); ++idx)
928  {
929  addAttribute(children[idx].get());
930  }
931 }
932 
934 {
935  clearAttributes();
936  addAttributes(children);
937 }
938 
940 {
941  theChildNodes.clear();
942  theAttributes.clear();
943  theTag="";
944  theText="";
945  theCDataFlag=false;
946 }
947 
949 {
950  theChildNodes.clear();
951 }
952 
954 {
955  theAttributes.clear();
956 }
957 
959  const ossimString& prefix)const
960 {
961  ossimString name = getTag();
962  ossimString value = getText();
963 
964  ossimString copyPrefix = prefix;
965 
966  if(name != "")
967  {
968  copyPrefix += (name+".");
969  }
970  if(theChildNodes.size() < 1)
971  {
972  kwl.add(prefix+name,
973  value,
974  true);
975  }
976 
977  ossimString attributePrefix = copyPrefix + "@";
978  ossim_uint32 attributeIdx = 0;
979  for(attributeIdx = 0; attributeIdx < theAttributes.size(); ++attributeIdx)
980  {
981  kwl.add(attributePrefix+theAttributes[attributeIdx]->getName(),
982  theAttributes[attributeIdx]->getValue(),
983  true);
984  }
985 
986  ossim_uint32 idx = 0;
987  for(idx = 0; idx < theChildNodes.size();++idx)
988  {
989  theChildNodes[idx]->toKwl(kwl,
990  copyPrefix);
991  }
992 }
993 
995  ossimString& tag)
996 {
997  if(traceDebug())
998  {
1000  << "ossimXmlNode::readTag: entered ......\n";
1001  }
1002  xmlskipws(in);
1003 
1004  tag.clear();
1005  int c = in.peek();
1006 
1007  // bool validTag = false;
1008  // while(!validTag)
1009  {
1010  while( (c != ' ')&&
1011  (c != '\n')&&
1012  (c != '\t')&&
1013  (c != '\r')&&
1014  (c != '<')&&
1015  (c != '>')&&
1016  (c != '/')&&
1017  (!in.fail()))
1018  {
1019  tag += (char)c;
1020  in.ignore(1);
1021  c = in.peek();
1022  if(tag == "!--") // ignore comment tags
1023  {
1024  tag = "--";
1025  break;
1026  }
1027  }
1028  }
1029 
1030  if(traceDebug())
1031  {
1033  << "ossimXmlNode::readTag: leaving ......\n";
1034  }
1035 
1036  return (!tag.empty())&&(!in.fail());
1037 }
1038 
1040 {
1041  if(traceDebug())
1042  {
1044  << "ossimXmlNode::readCDataContent: entered ...\n";
1045  }
1046 
1047  // Ignore up to "]]>"
1048 
1049  bool result = false;
1050 
1051  char c;
1052 
1053  while(!in.fail())
1054  {
1055  c = in.get();
1056  if ( c != ']' )
1057  {
1058  theText += c;
1059  }
1060  else // at "]"
1061  {
1062  c = in.get();
1063  if( c == ']' ) // at "]]"
1064  {
1065  c = in.get();
1066  if( c == '>' )
1067  {
1068  //in >> xmlskipws;
1069  result = true;
1070  break;
1071  }
1072  }
1073  }
1074  }
1075 
1076  if(traceDebug())
1077  {
1079  << "theText: " << theText
1080  << "\nexit status: " << (result?"true":"false")
1081  << "\nossimXmlNode::readCDataContent: leaving ...\n";
1082  }
1083 
1084  return result;
1085 }
1086 
1087 #if 0
1089 {
1090  xmlskipws(in);
1091 
1092  theText = "";
1093  theCDataFlag = false;
1094 
1095  char buf[9];
1096  buf[8]='\0';
1097 
1098  std::streampos initialPos = in.tellg();
1099 
1100  in.read(buf,9);
1101  ossimString ostrBuf(buf);
1102 
1103  if(ostrBuf == "<![CDATA[")
1104  {
1105  if(readCDataContent(in))
1106  {
1107  theCDataFlag = true;
1108  return true;
1109  }
1110  else
1111  {
1112  return false;
1113  }
1114  }
1115  else if(ostrBuf.substr(0,4) == "<!--")
1116  {
1117  in.seekg(initialPos);
1118  char c = in.get();
1119  // Strip comment
1120  while(!in.fail()) // continue until we see a --> pattern
1121  {
1122  c = in.get();
1123  if(c == '-')
1124  {
1125  c = in.get();
1126  if(c == '-')
1127  {
1128  c = in.get();
1129  if(c == '>')
1130  {
1131  break;
1132  }
1133  }
1134  }
1135  }
1136  }
1137  else if(ostrBuf.substr(0,1) == "<")
1138  {
1139  in.seekg(initialPos);
1140  }
1141  else
1142  {
1143  in.seekg(initialPos);
1144  char c = in.peek();
1145  while(!in.fail() && c != '<')
1146  {
1147  theText += (char)in.get();
1148  c = in.peek();
1149  }
1150  }
1151  return !in.fail();
1152 }
1153 #endif
1154 #if 0
1156 {
1157  xmlskipws(in);
1158 
1159  theText = "";
1160  theCDataFlag = false;
1161  char c = in.peek();
1162 
1163  do
1164  {
1165  if(c == '<')
1166  {
1167  in.ignore();
1168 
1169  // we will check for comments or CDATA
1170  if(in.peek()=='!')
1171  {
1172  char buf1[4];
1173  buf1[3] = '\0';
1174  in.read(buf1, 3);
1175  if(ossimString(buf1) == "!--")
1176  {
1177  // special text read
1178  theText += buf1;
1179  bool done = false;
1180  do
1181  {
1182  if(in.peek() != '-')
1183  {
1184  in.ignore();
1185  }
1186  else
1187  {
1188  in.ignore();
1189  if(in.peek() == '-')
1190  {
1191  in.ignore();
1192  if(in.peek() == '>')
1193  {
1194  in.ignore();
1195  done = true;
1196  c = in.peek();
1197  }
1198  }
1199  }
1200  }while(!done&&!in.fail());
1201  }
1202  else
1203  {
1204 
1205  char buf2[6];
1206  buf2[5] = '\0';
1207  in.read(buf2, 5);
1208  if(in.fail())
1209  {
1210  return false;
1211  }
1212  if(ossimString(buf1)+ossimString(buf2) == "![CDATA[")
1213  {
1214  if(readCDataContent(in))
1215  {
1216  theCDataFlag = true;
1217  return true;
1218  }
1219  }
1220  }
1221  }
1222  else
1223  {
1224  in.putback(c);
1225  return true;
1226  }
1227  }
1228  else
1229  {
1230  theText += (char)in.get();
1231  c = in.peek();
1232  }
1233  }while(!in.fail());
1234 
1235  return !in.fail();
1236 }
1237 #endif
1238 
1240 {
1241  if(traceDebug())
1242  {
1244  << "ossimXmlNode::readTextContent: entered ...\n";
1245  }
1246 
1247  //---
1248  // Parse the text string. Do it with no peeks, ignores, or putbacks as
1249  // those seem to have issues on Windows (vs9).
1250  //---
1251  bool result = false;
1252 
1253  theText = "";
1254  theCDataFlag = false;
1255 
1256  xmlskipws(in);
1257 
1258  if ( !in.fail() )
1259  {
1260  std::streampos initialPos = in.tellg();
1261 
1262  char c = in.get();
1263 
1264  if ( c != '<' )
1265  {
1266  do // Get the text up to the next '<'.
1267  {
1268  theText += c;
1269  c = in.get();
1270  } while ( (c != '<') && !in.fail() );
1271 
1272  in.unget(); // Put '<' back.
1273  result = !in.fail();
1274  }
1275  else // At "<" see if comment
1276  {
1277  c = in.get();
1278 
1279  if ( c != '!' )
1280  {
1281  in.seekg(initialPos);
1282  result = !in.fail();
1283  }
1284  else // at "<!"
1285  {
1286  c = in.get();
1287  if ( c == '-' )
1288  {
1289  // Comment section: <!-- some comment -->
1290  c = in.get();
1291  if ( c == '-' ) // at "<!--"
1292  {
1293  // Strip comment
1294  while( !in.fail() ) // continue until we see a --> pattern
1295  {
1296  c = in.get();
1297  if(c == '-')
1298  {
1299  c = in.get();
1300  if(c == '-')
1301  {
1302  c = in.get();
1303  if(c == '>')
1304  {
1305  result = !in.fail();
1306  break;
1307  }
1308  }
1309  }
1310  }
1311  }
1312  }
1313  else if ( c == '[' ) // at "<!["
1314  {
1315  // CDATA section: <![CDATA[something-here]]>
1316  c = in.get();
1317  if ( c == 'C') // at "<![C:"
1318  {
1319  c = in.get();
1320  if ( c == 'D' )// at "<![CD"
1321  {
1322  c = in.get();
1323  if ( c == 'A' ) // at "<![CDA"
1324  {
1325  c = in.get();
1326  if ( c == 'T' ) // at "<![CDAT"
1327  {
1328  c = in.get();
1329  if ( c == 'A' ) // at "<![CDATA"
1330  {
1331  c = in.get();
1332  if ( c == '[' ) // at "<!CDATA["
1333  {
1334  if (readCDataContent(in))
1335  {
1336  theCDataFlag = true;
1337  result = true;
1338  }
1339  }
1340  }
1341  }
1342  }
1343  }
1344  }
1345  }
1346  }
1347  }
1348  }
1349 
1350  if(traceDebug())
1351  {
1353  << "theText: " << theText
1354  << "\ntheCDataFlag: " << (theCDataFlag?"true":"false")
1355  << "\nexit status: " << (result?"true":"false")
1356  << "\nossimXmlNode::readTextContent: leaving ...\n";
1357  }
1358 
1359  return result;
1360 }
1361 
1363  ossimString& endTag)
1364 {
1365  bool result = false;
1366  char c = in.peek();
1367  endTag = "";
1368 
1369  if(theTag == "--")// this is a comment tag
1370  {
1371  skipCommentTag(in);
1372  endTag = "--";
1373  return (!in.fail());
1374  }
1375  // check end tag
1376  //
1377  if(c == '/')
1378  {
1379  in.ignore();
1380  readTag(in, endTag);
1381  if(in.fail()) return false;
1382  xmlskipws(in);
1383  c = in.peek();
1384  result = true;
1385  }
1386  else
1387  {
1388  return false;
1389  }
1390  if(c != '>')
1391  {
1392  setErrorStatus();
1393  return false;
1394  }
1395  else
1396  {
1397  in.ignore(1);
1398  }
1399  if(in.fail()) result = false;
1400 
1401  return result;
1402 }
ossimXmlNode * theParentNode
Definition: ossimXmlNode.h:119
void clear()
Erases the entire container.
Definition: ossimString.h:432
ossimString theText
Definition: ossimXmlNode.h:122
void setTag(const ossimString &tag)
bool read(std::istream &in)
void setText(const ossimString &text)
RTTI_DEF2(ossimXmlNode, "ossimXmlNode", ossimObject, ossimErrorStatusInterface)
void findChildNodes(const ossimString &rel_xpath, ossimXmlNode::ChildListType &nodelist) const
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
bool read(std::istream &in)
ossimString theTag
Definition: ossimXmlNode.h:118
const ossimXmlNode::ChildListType & getChildNodes() const
ossimString const & getTag() const
Definition: ossimXmlNode.h:53
void duplicateChildren(ossimXmlNode::ChildListType &result) const
std::vector< ossimRefPtr< ossimXmlAttribute > > AttributeListType
Definition: ossimXmlNode.h:31
vector< ossimRefPtr< ossimXmlAttribute > > theAttributes
Definition: ossimXmlNode.h:121
bool readTag(std::istream &in, ossimString &tag)
const ossimString & getValue() const
ossimRefPtr< ossimXmlNode > addNode(const ossimString &relPath, const ossimString &text="")
const ossimRefPtr< ossimXmlNode > & findFirstNode(const ossimString &rel_xpath) const
void toKwl(ossimKeywordlist &kwl, const ossimString &prefix="") const
ossimRefPtr< ossimXmlNode > removeChild(ossimRefPtr< ossimXmlNode > node)
void clearAttributes()
ostream & operator<<(ostream &os, const ossimXmlNode &xml_node)
ossimRefPtr< ossimXmlNode > addOrSetNode(const ossimString &relPath, const ossimString &text="")
std::vector< ossimRefPtr< ossimXmlNode > > ChildListType
Definition: ossimXmlNode.h:30
bool readTextContent(std::istream &in)
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
void setValue(const ossimString &value)
bool getAttributeValue(ossimString &value, const ossimString &name) const
const ossimString & getText() const
Definition: ossimXmlNode.h:92
void addChildren(ossimXmlNode::ChildListType &children)
ossimRefPtr< ossimXmlAttribute > findAttribute(const ossimString &name)
void addAttributes(ossimXmlNode::AttributeListType &children)
const ossimXmlNode * getParentNode() const
std::string::size_type size() const
Definition: ossimString.h:405
void duplicateAttributes(ossimXmlNode::AttributeListType result) const
unsigned int ossim_uint32
bool readEndTag(std::istream &in, ossimString &endTag)
void skipCommentTag(std::istream &in)
const ossimXmlNode::AttributeListType & getAttributes() const
bool readCDataContent(std::istream &in)
void setParent(ossimXmlNode *parent)
bool cdataFlag() const
std::basic_istream< char > istream
Base class for char input streams.
Definition: ossimIosFwd.h:20
void setAttributes(ossimXmlNode::AttributeListType &children)
vector< ossimRefPtr< ossimXmlNode > > theChildNodes
Definition: ossimXmlNode.h:120
void setChildren(ossimXmlNode::ChildListType &children)
bool setAttribute(const ossimString &name, const ossimString &value, bool addIfNotPresentFlag=false)
void setCDataFlag(bool value)
bool empty() const
Definition: ossimString.h:411
bool getChildTextValue(ossimString &value, const ossimString &relPath) const
std::string substr(std::string::size_type pos=0, std::string::size_type n=std::string::npos) const
Equivalent to basic_string(*this, pos, n).
Definition: ossimString.h:910
void addAttribute(ossimRefPtr< ossimXmlAttribute > attribute)
void clearChildren()
void addChildNode(ossimRefPtr< ossimXmlNode > node)
std::string::size_type find(const std::string &s, std::string::size_type pos=0) const
Searches for s as a substring of *this, beginning at character pos of *this.
Definition: ossimString.h:753
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
virtual ossimObject * dup() const
Definition: ossimXmlNode.h:36