Simbody  3.8
Xml.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_XML_H_
2 #define SimTK_SimTKCOMMON_XML_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2010-15 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: Peter Eastman *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
30 
31 #include <iterator>
32 #include <iostream>
33 
34 namespace SimTK {
35 
36 // These are declared but never defined; all TinyXML code is hidden.
37 class TiXmlNode;
38 class TiXmlElement;
39 class TiXmlAttribute;
40 class TiXmlText;
41 class TiXmlComment;
42 class TiXmlUnknown;
43 
45 namespace Xml {
46 
47 // These classes are defined below.
48 class Attribute;
49 class Node; // This is the abstract handle type for any node.
50 class Comment; // These are the concrete node types.
51 class Unknown; // "
52 class Text; // "
53 class Element; // "
54 
55 // This provides iteration over all the attributes found in a given element.
56 class attribute_iterator;
57 
58 // This provides iteration over all the nodes, or nodes of a certain type,
59 // at either the Xml document level or over the child nodes of an element.
60 class node_iterator;
61 
62 // This provides iteration over all the element nodes that are children
63 // of a given element, or over the subset of those child elements that has
64 // a particular tag word.
65 class element_iterator;
66 
72 enum NodeType {
73  NoNode = 0x00,
74  ElementNode = 0x01,
75  TextNode = 0x02,
76  CommentNode = 0x04,
77  UnknownNode = 0x08,
78 
82 };
83 
86 
304 //------------------------------------------------------------------------------
305 // XML :: DOCUMENT
306 //------------------------------------------------------------------------------
308 public:
312 
322 
328 explicit Document(const String& pathname);
329 
332 Document(const Document& source);
333 
337 Document& operator=(const Document& souce);
338 
341 
343 void clear();
353 void readFromFile(const String& pathname);
358 void writeToFile(const String& pathname) const;
362 void readFromString(const String& xmlDocument);
366 void readFromString(const char* xmlDocument);
372 void writeToString(String& xmlDocument, bool compact = false) const;
377 void setIndentString(const String& indent);
380 const String& getIndentString() const;
381 
385 static void setXmlCondenseWhiteSpace(bool shouldCondense);
400 
413 
416 const String& getRootTag() const;
419 void setRootTag(const String& tag);
420 
428 void insertTopLevelNodeAfter (const node_iterator& afterThis,
429  Node insertThis);
433  Node insertThis);
439 void eraseTopLevelNode(const node_iterator& deleteThis);
463 
498 bool getXmlIsStandalone() const;
499 
502 void setXmlVersion(const String& version);
505 void setXmlEncoding(const String& encoding);
510 void setXmlIsStandalone(bool isStandalone);
513 //------------------------------------------------------------------------------
514  private:
515 friend class Node;
516 
517 class Impl; // a private, local class Document::Impl
518 const Impl& getImpl() const {assert(impl); return *impl;}
519 Impl& updImpl() {assert(impl); return *impl;}
520 
521 Document& unconst() const {return *const_cast<Document*>(this);}
522 
523 Impl* impl; // This is the lone data member.
524 };
525 
530 // Do this inline so we don't have to pass the ostream through the API.
531 inline std::ostream& operator<<(std::ostream& o, const Document& doc) {
532  String output;
533  doc.writeToString(output);
534  return o << output;
535 }
536 
537 
538 
539 //------------------------------------------------------------------------------
540 // XML ATTRIBUTE
541 //------------------------------------------------------------------------------
548 public:
550 Attribute() : tiAttr(0) {}
553 Attribute(const String& name, const String& value);
557 Attribute(const Attribute& src) : tiAttr(src.tiAttr) {}
563 { if (&src!=this) {clear(); tiAttr=src.tiAttr;} return *this; }
567 ~Attribute() {clear();}
569 bool isValid() const {return tiAttr!=0;}
574 bool isOrphan() const;
576 const String& getName() const;
579 const String& getValue() const;
582 Attribute& setName(const String& name);
586 Attribute& setValue(const String& value);
587 
591 void clear();
595 void clearOrphan();
596 
601 void writeToString(String& out) const;
602 
606 bool operator==(const Attribute& attr) const {return tiAttr==attr.tiAttr;}
607 bool operator!=(const Attribute& attr) const {return tiAttr!=attr.tiAttr;}
608 
609 //------------------------------------------------------------------------------
610  private:
611 friend class attribute_iterator;
612 friend class Element;
613 
614 explicit Attribute(TiXmlAttribute* attr) {tiAttr=attr;}
615 const TiXmlAttribute& getTiAttr() const {assert(tiAttr);return *tiAttr;}
616 TiXmlAttribute& updTiAttr() {assert(tiAttr);return *tiAttr;}
617 
618 // Careful; this does not clear the handle before replacing the pointer
619 // so should not be used if this could be the owner handle of an attribute
620 // that hasn't ever been added to a document. It is intended for use by
621 // iterators, whose contained Attributes can never be owners.
622 void setTiAttrPtr(TiXmlAttribute* attr) {tiAttr=attr;}
623 const TiXmlAttribute* getTiAttrPtr() const {return tiAttr;}
624 TiXmlAttribute* updTiAttrPtr() {return tiAttr;}
625 
626 Attribute& unconst() const {return *const_cast<Attribute*>(this);}
627 
628 TiXmlAttribute* tiAttr; // this is the lone data member
629 };
630 
635 // Do this inline so we don't have to pass the ostream through the API.
636 inline std::ostream& operator<<(std::ostream& o, const Attribute& attr) {
637  String output;
638  attr.writeToString(output);
639  return o << output;
640 }
641 
642 
643 
644 //------------------------------------------------------------------------------
645 // XML ATTRIBUTE ITERATOR
646 //------------------------------------------------------------------------------
650 public:
651  using iterator_category = std::bidirectional_iterator_tag;
653  using difference_type = std::ptrdiff_t;
654  using pointer = Attribute*;
656 
662 explicit attribute_iterator(Attribute& attr) : attr(attr) {}
666 : attr(src->updTiAttrPtr()) {}
668 ~attribute_iterator() {attr.setTiAttrPtr(0);}
672 { attr.setTiAttrPtr(src->updTiAttrPtr()); return *this; }
689 
690 // It's the iterator that's const in these next two methods; it still points
691 // to a non-const object just like a char* const p.
692 
695 Attribute& operator*() const {return const_cast<Attribute&>(attr);}
699 Attribute* operator->() const {return const_cast<Attribute*>(&attr);}
704 bool operator==(const attribute_iterator& other) const
705 { return other.attr==attr; }
707 bool operator!=(const attribute_iterator& other) const
708 { return other.attr!=attr; }
709 
710 //------------------------------------------------------------------------------
711  private:
712 friend class Element;
713 
714 explicit attribute_iterator(TiXmlAttribute* ap) : attr(ap) {}
715 
716 Attribute attr; // the lone data member
717 };
718 
719 
720 
721 //------------------------------------------------------------------------------
722 // XML :: NODE
723 //------------------------------------------------------------------------------
748 public:
749 
754 
757 Node() : tiNode(0) {}
761 Node(const Node& src) : tiNode(src.tiNode) {}
766 Node& operator=(const Node& src)
767 { if (&src!=this) {clear(); tiNode=src.tiNode;} return *this; }
771 Node clone() const;
775 ~Node() {clear();}
779 void clear();
783 void clearOrphan();
791 
795 
798 
801 bool isValid() const {return tiNode != 0;}
802 
806 bool isTopLevelNode() const;
807 
812 bool isOrphan() const;
813 
817 bool hasParentElement() const;
818 
829 
840 const String& getNodeText() const;
841 
848 void writeToString(String& out, bool compact=false) const;
854 bool operator==(const Node& other) const {return other.tiNode==tiNode;}
856 bool operator!=(const Node& other) const {return other.tiNode!=tiNode;}
857 
858 
859 //------------------------------------------------------------------------------
860  protected: // don't let Doxygen see these
862 explicit Node(TiXmlNode* tiNode) : tiNode(tiNode) {}
863 
864 const TiXmlNode& getTiNode() const {assert(tiNode);return *tiNode;}
865 TiXmlNode& updTiNode() {assert(tiNode);return *tiNode;}
866 
867 // Careful: these "Ptr" methods provide raw access to the contained
868 // pointer without any cleanup or error checking. In particular,
869 // setTiNodePtr() does not attempt to delete the current contents.
870 void setTiNodePtr(TiXmlNode* node) {tiNode=node;}
871 const TiXmlNode* getTiNodePtr() const {return tiNode;}
872 TiXmlNode* updTiNodePtr() {return tiNode;}
875 //------------------------------------------------------------------------------
876  private:
877 friend class Document;
878 friend class node_iterator;
879 friend class Comment;
880 friend class Unknown;
881 friend class Text;
882 friend class Element;
883 
884 Node& unconst() const {return *const_cast<Node*>(this);}
885 
886 TiXmlNode* tiNode; // the lone data member
887 };
888 
894 // Do this inline so we don't have to pass the ostream through the API.
895 inline std::ostream& operator<<(std::ostream& o, const Node& xmlNode) {
896  String output;
897  xmlNode.writeToString(output);
898  return o << output;
899 }
900 
901 
902 
903 //------------------------------------------------------------------------------
904 // XML :: NODE ITERATOR
905 //------------------------------------------------------------------------------
910 public:
911  using iterator_category = std::bidirectional_iterator_tag;
912  using value_type = Node;
913  using difference_type = std::ptrdiff_t;
914  using pointer = Node*;
915  using reference = Node&;
916 
917 explicit node_iterator(NodeType allowed=AnyNodes)
918 : allowed(allowed) {}
919 explicit node_iterator(Node& node, NodeType allowed=AnyNodes)
920 : node(node), allowed(allowed) {}
921 
925 : node(*src), allowed(src.allowed) {}
927 ~node_iterator() {node.setTiNodePtr(0);}
931 { node = *src; allowed = src.allowed; return *this; }
932 
934 node_iterator operator++(int); // postfix
936 node_iterator operator--(int); // postfix
937 Node& operator*() {return node;}
938 Node* operator->() {return &node;}
939 // It's the iterator that's const; it still points to a non-const object
940 // just like a char* const p.
941 Node& operator*() const {return const_cast<Node&>(node);}
942 Node* operator->() const {return const_cast<Node*>(&node);}
943 bool operator==(const node_iterator& other) const {return other.node==node;}
944 bool operator!=(const node_iterator& other) const {return other.node!=node;}
945 
946 //------------------------------------------------------------------------------
947  protected:
948 explicit node_iterator(TiXmlNode* tiNode, NodeType allowed=AnyNodes)
949 : node(tiNode), allowed(allowed) {}
950 void reassign(TiXmlNode* tiNode)
951 { node.setTiNodePtr(tiNode); }
952 
953 //------------------------------------------------------------------------------
954  private:
955 friend class Document;
956 friend class Node;
957 friend class Element;
958 friend class element_iterator;
959 
960 Node node; // data members
961 NodeType allowed;
962 };
963 
964 
965 
966 //------------------------------------------------------------------------------
967 // XML :: ELEMENT ITERATOR
968 //------------------------------------------------------------------------------
974 public:
975 
978 explicit element_iterator(const String& tag="")
979 : node_iterator(ElementNode), tag(tag) {}
982 inline explicit element_iterator(Element& elt, const String& tag=""); // below
983 
987 : node_iterator(src), tag(src.tag) {}
988 
992 { upcast()=src; tag = src.tag; return *this; }
993 
995 element_iterator operator++(int); // postfix
997 element_iterator operator--(int); // postfix
998 inline Element& operator*() const; // below
999 inline Element* operator->() const; // below
1000 
1001 bool operator==(const element_iterator& other) const
1002 { return other.upcast()==upcast();}
1003 bool operator!=(const element_iterator& other) const
1004 { return other.upcast()!=upcast();}
1005 
1006 //------------------------------------------------------------------------------
1007  private:
1008 friend class Element;
1009 
1010 explicit element_iterator(TiXmlElement* tiElt, const String& tag="")
1011 : node_iterator((TiXmlNode*)tiElt, ElementNode), tag(tag) {}
1012 void reassign(TiXmlElement* tiElt)
1013 { upcast().reassign((TiXmlNode*)tiElt); }
1014 
1015 const node_iterator& upcast() const
1016 { return *static_cast<const node_iterator*>(this); }
1017 node_iterator& upcast()
1018 { return *static_cast<node_iterator*>(this); }
1019 
1020 String tag; // lone data member
1021 };
1022 
1023 
1024 
1025 
1026 //------------------------------------------------------------------------------
1027 // XML :: ELEMENT
1028 //------------------------------------------------------------------------------
1043 public:
1044 
1052 
1055 Element() : Node() {}
1056 
1069 explicit Element(const String& tagWord, const String& value="");
1070 
1078 template <class T>
1079 Element(const String& tagWord, const T& value) :
1080  Element(tagWord, String(value)) { }
1081 
1092 template <class T>
1093 Element(const String& tagWord, const T& value, int precision) :
1094  Element(tagWord, String(value, precision)) { }
1095 
1099 Element clone() const;
1100 
1103 const String& getElementTag() const;
1105 void setElementTag(const String& tag);
1106 
1112 void insertNodeBefore(const node_iterator& pos, Node node);
1118 void insertNodeAfter(const node_iterator& pos, Node node);
1119 
1121 void appendNode(Node node) {insertNodeAfter(node_end(), node);}
1122 
1128 void eraseNode(const node_iterator& deleteThis);
1134 Node removeNode(const node_iterator& removeThis);
1148 
1154 bool isValueElement() const;
1155 
1163 const String& getValue() const;
1164 
1171 
1177 void setValue(const String& value);
1178 
1183 template <class T>
1184 void setValueAs(const T& value) {
1185  setValue(String(value));
1186 }
1187 
1195 template <class T>
1196 void setValueAs(const T& value, int precision) {
1197  // precision will be capped in the String constructor if needed.
1198  setValue(String(value, precision));
1199 }
1200 
1207 template <class T> T getValueAs() const
1208 { T out; convertStringTo(getValue(),out); return out;}
1209 
1212 template <class T> void getValueAs(T& out) const
1213 { convertStringTo(getValue(),out); }
1214 
1222 const String&
1224 { return unconst().getRequiredElement(tag).getValue(); }
1225 
1229 String
1230 getOptionalElementValue(const String& tag, const String& def="") const
1231 { const Element opt(unconst().getOptionalElement(tag));
1232  return opt.isValid() ? opt.getValue() : def; }
1233 
1242 template <class T> T
1244 { T out; convertStringTo(unconst().getRequiredElementValue(tag), out);
1245  return out; }
1246 
1258 template <class T> T
1259 getOptionalElementValueAs(const String& tag, const T& def) const
1260 { const Element opt(unconst().getOptionalElement(tag));
1261  if (!opt.isValid()) return def;
1262  T out; convertStringTo(opt.getValue(), out); return out; }
1272 bool hasAttribute(const String& name) const;
1273 
1276 void setAttributeValue(const String& name, const String& value);
1277 
1282 void eraseAttribute(const String& name);
1283 
1286 const String&
1288 { return unconst().getRequiredAttribute(name).getValue(); }
1289 
1296 template <class T> T
1298 { T out; convertStringTo(getRequiredAttributeValue(name),out); return out; }
1299 
1306 String
1307 getOptionalAttributeValue(const String& name, const String& def="") const
1308 { Attribute attr = unconst().getOptionalAttribute(name);
1309  if (!attr.isValid()) return def;
1310  return attr.getValue(); }
1311 
1322 template <class T> T
1323 getOptionalAttributeValueAs(const String& name, const T& def) const
1324 { Attribute attr = unconst().getOptionalAttribute(name);
1325  if (!attr.isValid()) return def;
1326  T out; convertStringTo(attr.getValue(), out); return out; }
1327 
1331 
1336 
1346 { return Array_<Attribute>(attribute_begin(), attribute_end()); }
1347 
1348 
1369 
1371 bool hasElement(const String& tag) const;
1374 bool hasNode(NodeType allowed=AnyNodes) const;
1375 
1381 
1386 
1395 { return Array_<Element>(element_begin(tag), element_end()); }
1396 
1404 { return Array_<Node>(node_begin(allowed), node_end()); }
1405 
1414 
1430 static bool isA(const Node&);
1433 static const Element& getAs(const Node& node);
1436 static Element& getAs(Node& node);
1439 //------------------------------------------------------------------------------
1440  private:
1441 friend class Node;
1442 friend class element_iterator;
1443 
1444 explicit Element(TiXmlElement* tiElt)
1445 : Node(reinterpret_cast<TiXmlNode*>(tiElt)) {}
1446 
1447 TiXmlElement& updTiElement()
1448 { return reinterpret_cast<TiXmlElement&>(updTiNode()); }
1449 const TiXmlElement& getTiElement() const
1450 { return reinterpret_cast<const TiXmlElement&>(getTiNode()); }
1451 
1452 // Careful: these "Ptr" methods provide raw access to the contained
1453 // pointer without any cleanup or error checking. In particular,
1454 // setTiElementPtr() does not attempt to delete the current contents.
1455 const TiXmlElement* getTiElementPtr() const
1456 { return reinterpret_cast<const TiXmlElement*>(getTiNodePtr()); }
1457 TiXmlElement* updTiElementPtr()
1458 { return reinterpret_cast<TiXmlElement*>(updTiNodePtr()); }
1459 void setTiElementPtr(TiXmlElement* elt)
1460 { setTiNodePtr(reinterpret_cast<TiXmlNode*>(elt)); }
1461 
1462 Element& unconst() const {return *const_cast<Element*>(this);}
1463 
1464 
1465 // no data members; see Node
1466 };
1467 
1468 
1469 
1470 // A few element_iterator inline definitions had to wait for Element to be
1471 // defined.
1473  (Element& elt, const String& tag)
1474 : node_iterator(elt, ElementNode), tag(tag) {}
1476 { return Element::getAs(*upcast());}
1478 { return &Element::getAs(*upcast());}
1479 
1480 
1481 
1482 
1483 //------------------------------------------------------------------------------
1484 // XML :: TEXT NODE
1485 //------------------------------------------------------------------------------
1488 public:
1491 Text() : Node() {}
1492 
1495 explicit Text(const String& text);
1496 
1500 Text clone() const;
1501 
1504 const String& getText() const;
1508 
1514 static bool isA(const Node&);
1517 static const Text& getAs(const Node& node);
1520 static Text& getAs(Node& node);
1523 //------------------------------------------------------------------------------
1524  private:
1525 // no data members; see Node
1526 
1527 explicit Text(TiXmlText* tiText)
1528 : Node(reinterpret_cast<TiXmlNode*>(tiText)) {}
1529 };
1530 
1531 
1532 
1533 //------------------------------------------------------------------------------
1534 // XML :: COMMENT NODE
1535 //------------------------------------------------------------------------------
1538 public:
1541 Comment() : Node() {}
1542 
1547 explicit Comment(const String& text);
1548 
1552 Comment clone() const;
1553 
1559 static bool isA(const Node&);
1562 static const Comment& getAs(const Node& node);
1565 static Comment& getAs(Node& node);
1568 //------------------------------------------------------------------------------
1569  private:
1570 // no data members; see Node
1571 
1572 explicit Comment(TiXmlComment* tiComment)
1573 : Node(reinterpret_cast<TiXmlNode*>(tiComment)) {}
1574 };
1575 
1576 
1577 
1578 //------------------------------------------------------------------------------
1579 // XML :: UNKNOWN NODE
1580 //------------------------------------------------------------------------------
1583 public:
1586 Unknown() : Node() {}
1587 
1593 explicit Unknown(const String& contents);
1594 
1598 Unknown(Element& element, const String& contents)
1599 { new(this) Unknown(contents);
1600  element.insertNodeBefore(element.node_end(), *this); }
1601 
1605 Unknown clone() const;
1606 
1609 const String& getContents() const;
1612 void setContents(const String& contents);
1613 
1619 static bool isA(const Node&);
1622 static const Unknown& getAs(const Node& node);
1625 static Unknown& getAs(Node& node);
1628 //------------------------------------------------------------------------------
1629  private:
1630 // no data members; see Node
1631 
1632 explicit Unknown(TiXmlUnknown* tiUnknown)
1633 : Node(reinterpret_cast<TiXmlNode*>(tiUnknown)) {}
1634 };
1635 
1636 } // end of namespace Xml
1637 
1638 
1661 template <class T> inline Xml::Element
1662 toXmlElement(const T& thing, const std::string& name) {
1663  std::ostringstream os;
1664  writeUnformatted(os, thing);
1665  return Xml::Element(name.empty()?"value":name, os.str());
1666 }
1667 
1671 template <class T> inline
1672 auto toXmlElementHelper(const T& thing, const std::string& name, bool)
1673  -> decltype(std::declval<T>().toXmlElement(name)) {
1674  return thing.toXmlElement(name); // call member function
1675 }
1676 
1680 template <class T> inline
1681 auto toXmlElementHelper(const T& thing, const std::string& name, int)
1682  -> Xml::Element {
1683  return toXmlElement(thing, name); // call free function
1684 }
1685 
1707 template <class T> inline void
1709  const std::string& requiredName="") {
1710  if (!requiredName.empty()) {
1711  const String& name = elt.getElementTag();
1712  SimTK_ERRCHK2_ALWAYS(name==requiredName, "fromXmlElement<T>",
1713  "Expected element name '%s' but got '%s'.", requiredName.c_str(),
1714  name.c_str());
1715  }
1716  std::istringstream is(elt.getValue());
1717  const bool readOK = readUnformatted(is, thing);
1718  SimTK_ERRCHK2_ALWAYS(readOK, "fromXmlElement<T>",
1719  "Failed to read an object of type T='%s' from element value '%s' "
1720  "using readUnformatted<T>().",
1721  NiceTypeName<T>::namestr().c_str(), elt.getValue().c_str());
1722 }
1723 
1727 template <class T> inline
1729  const std::string& requiredTag, bool)
1730  -> decltype(std::declval<T>().fromXmlElement(elt,requiredTag)) {
1731  return thing.fromXmlElement(elt,requiredTag); // call member function
1732 }
1733 
1737 template <class T> inline
1739  const std::string& requiredTag, int)
1740  -> void {
1741  fromXmlElement(thing, elt, requiredTag); // call free function
1742 }
1743 
1744 
1745 // Definition of these functions (which should really be methods of
1746 // the Array_ classes) has to wait until Xml classes are declared because Xml
1747 // uses Array_.
1748 
1759 template <class T, class X>
1761  const std::string& name="") {
1762  static const int version = 1;
1763  Xml::Element e("Array");
1764  if (!name.empty()) e.setAttributeValue("name", name);
1765  e.setAttributeValue("version", String(version));
1766  for (const auto& v : thing)
1767  e.appendNode(toXmlElementHelper(v, "", true));
1768  return e;
1769 }
1770 
1776 template <class T, class X>
1778  const std::string& name="") {
1779  return toXmlElement(static_cast<const ArrayViewConst_<T,X>&>(thing),name);
1780 }
1781 
1787 template <class T, class X>
1789  const std::string& name="") {
1790  return toXmlElement(static_cast<const ArrayViewConst_<T,X>&>(thing),name);
1791 }
1792 
1793 } // namespace SimTK
1794 
1795 #endif // SimTK_SimTKCOMMON_XML_H_
1796 
1797 
This file defines the Array_<T,X> class and related support classes including base classes ArrayViewC...
#define SimTK_ERRCHK2_ALWAYS(cond, whereChecked, fmt, a1, a2)
Definition: ExceptionMacros.h:289
Mandatory first inclusion for any Simbody source or header file.
#define SimTK_SimTKCOMMON_EXPORT
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:224
This Array_ helper class is the base class for ArrayView_ which is the base class for Array_; here we...
Definition: Array.h:324
Xml::Element toXmlElement(const ArrayViewConst_< T, X > &thing, const std::string &name="")
Partial specialization for XML serialization of ArrayViewConst_ objects.
Definition: Xml.h:1760
This Array_ helper class is the base class for Array_, extending ArrayViewConst_ to add the ability t...
Definition: Array.h:845
Xml::Element toXmlElement(const ArrayView_< T, X > &thing, const std::string &name="")
Partial specialization for XML serialization of ArrayView_ objects.
Definition: Xml.h:1777
The Array_<T> container class is a plug-compatible replacement for the C++ standard template library ...
Definition: Array.h:1520
Xml::Element toXmlElement(const Array_< T, X > &thing, const std::string &name="")
Partial specialization for XML serialization of Array_ objects.
Definition: Xml.h:1788
SimTK::String is a plug-compatible std::string replacement (plus some additional functionality) inten...
Definition: String.h:65
Elements can have attributes, which are name="value" pairs that appear within the element start tag i...
Definition: Xml.h:547
~Attribute()
The Attribute handle destructor does not recover heap space so if you create orphan attributes and th...
Definition: Xml.h:567
Attribute & setName(const String &name)
If this is a valid attribute handle, change its name.
Attribute(const Attribute &src)
Copy constructor is shallow; that is, this handle will refer to the same attribute as the source.
Definition: Xml.h:557
bool operator==(const Attribute &attr) const
Comparison operators return true if the same attribute is being referenced or both handles are empty.
Definition: Xml.h:606
Attribute & setValue(const String &value)
If this is a valid attribute handle, change its value to the given String which should not be quoted.
void clear()
This method restores the Attribute handle to its default-constructed state but does not recover any h...
bool isValid() const
Is this handle currently holding an attribute?
Definition: Xml.h:569
Attribute & operator=(const Attribute &src)
Copy assignment is shallow; the handle is first cleared and then will refer to the same attribute as ...
Definition: Xml.h:562
void writeToString(String &out) const
Serialize this attribute to the given String.
void clearOrphan()
This method explicitly frees the heap space for an orphan attribute that was created but never insert...
const String & getValue() const
If this is a valid attribute handle, get the value of the attribute as a String, not including the qu...
bool operator!=(const Attribute &attr) const
Definition: Xml.h:607
Attribute()
Default constructor creates a null Attribute handle.
Definition: Xml.h:550
Attribute(const String &name, const String &value)
Create a new orphan Attribute, that is, an Attribute that is not owned by any Xml Element.
std::ostream & operator<<(std::ostream &o, const Attribute &attr)
Output a textual representation of the given Xml::Attribute to an std::ostream.
Definition: Xml.h:636
const String & getName() const
If this is a valid attribute handle, get the name of the attribute.
bool isOrphan() const
Return true if this Attribute is an orphan, meaning that it is not empty, but is not owned by any ele...
A comment contains only uninterpreted text.
Definition: Xml.h:1537
Comment()
Create an empty Comment node handle, suitable only for holding references to other Comment nodes.
Definition: Xml.h:1541
static const Comment & getAs(const Node &node)
Recast a Node to a const Comment, throwing an error if the Node is not actually an Comment node.
Comment(const String &text)
Create a new Comment node with the given text; the node is not yet owned by any XML document.
static Comment & getAs(Node &node)
Recast a writable Node to a writable Comment, throwing an error if the Node is not actually an Commen...
Comment clone() const
The clone() method makes a deep copy of this Comment node and returns a new orphan Comment node with ...
static bool isA(const Node &)
Test whether a given Node is an Comment node.
This class provides a minimalist capability for reading and writing XML documents,...
Definition: Xml.h:307
Document(const String &pathname)
Create a new XML document and initialize it from the contents of the given file name.
void clear()
Restore this document to its default-constructed state.
String getXmlVersion() const
Returns the Xml "version" attribute as a string (from the declaration line at the beginning of the do...
void setXmlVersion(const String &version)
Set the Xml "version" attribute; this will be written to the "declaration" line which is first in any...
void insertTopLevelNodeBefore(const node_iterator &beforeThis, Node insertThis)
Insert a top-level Comment or Unknown node just before the location indicated by the node_iterator.
void readFromFile(const String &pathname)
Read the contents of this Xml::Document from the file whose pathname is supplied.
void eraseTopLevelNode(const node_iterator &deleteThis)
Delete the indicated top-level node, which must not be the root element, and must not be node_end().
void insertTopLevelNodeAfter(const node_iterator &afterThis, Node insertThis)
Insert a top-level Comment or Unknown node just after the location indicated by the node_iterator,...
const String & getRootTag() const
Shortcut for getting the tag word of the root element which is usually the document type.
static void setXmlCondenseWhiteSpace(bool shouldCondense)
Set global mode to control whether white space is preserved or condensed down to a single space (affe...
Document & operator=(const Document &souce)
Copy assignment frees all heap space associated with the current Xml::Document and then makes a deep ...
bool getXmlIsStandalone() const
Returns the Xml "standalone" attribute as a bool (from the declaration line at the beginning of the d...
void readFromString(const char *xmlDocument)
Alternate form that reads from a null-terminated C string (char*) rather than a C++ string object.
const String & getIndentString() const
Return the current value of the indent string. The default is four spaces.
Document(const Document &source)
Copy constructor makes a deep copy of the entire source document; nothing is shared between the sourc...
void readFromString(const String &xmlDocument)
Read the contents of this Xml::Document from the supplied string.
void setIndentString(const String &indent)
Set the string to be used for indentation when we produce a "pretty-printed" serialized form of this ...
Element getRootElement()
Return an Element handle referencing the top-level element in this Xml::Document, known as the "root ...
Document()
Create an empty XML Document with default declaration and default root element with tag "_Root".
void writeToString(String &xmlDocument, bool compact=false) const
Write the contents of this in-memory Xml::Document to the supplied string.
node_iterator node_end() const
This node_end() iterator indicates the end of a sequence of nodes regardless of the NodeType restrict...
void writeToFile(const String &pathname) const
Write the contents of this in-memory Xml::Document to the file whose pathname is supplied.
void setRootTag(const String &tag)
Shortcut for changing the tag word of the root element which is usually the document type.
String getXmlEncoding() const
Returns the Xml "encoding" attribute as a string (from the declaration line at the beginning of the d...
std::ostream & operator<<(std::ostream &o, const Document &doc)
Output a "pretty printed" textual representation of the given Xml::Document to an std::ostream,...
Definition: Xml.h:531
node_iterator node_begin(NodeType allowed=AnyNodes)
Obtain an iterator to all the top-level nodes or a subset restricted via the allowed NodeType mask.
static bool isXmlWhiteSpaceCondensed()
Return the current setting of the global "condense white space" option.
void setXmlEncoding(const String &encoding)
Set the Xml "encoding" attribute; this doesn't affect the in-memory representation but can affect how...
~Document()
The destructor cleans up all heap space associated with this document.
void setXmlIsStandalone(bool isStandalone)
Set the Xml "standalone" attribute; this is normally true (corresponding to standalone="yes") and won...
Node removeTopLevelNode(const node_iterator &removeThis)
Remove the indicated top-level node from the document, returning it as an orphan rather than erasing ...
An element has (1) a tagword, (2) a map of (name,value) pairs called attributes, and (3) a list of ch...
Definition: Xml.h:1042
void eraseAttribute(const String &name)
Erase an attribute of this element if it exists, otherwise do nothing.
void setValueAs(const T &value)
Set the value of this value element to the text equivalent of any type T for which a conversion const...
Definition: Xml.h:1184
auto fromXmlElementHelper(T &thing, Xml::Element &elt, const std::string &requiredTag, bool) -> decltype(std::declval< T >().fromXmlElement(elt, requiredTag))
Helper function for fromXmlElement() that selects the member function if it exists.
Definition: Xml.h:1728
T getOptionalElementValueAs(const String &tag, const T &def) const
Convert the text value of an optional child value element, if present, to the type of the template ar...
Definition: Xml.h:1259
T getRequiredElementValueAs(const String &tag) const
Convert the text value of a required child value element to the type of the template argument T.
Definition: Xml.h:1243
void setValueAs(const T &value, int precision)
Set the value of this value element to the text equivalent of any type T for which a conversion const...
Definition: Xml.h:1196
auto toXmlElementHelper(const T &thing, const std::string &name, bool) -> decltype(std::declval< T >().toXmlElement(name))
Helper function for toXmlElement() that selects the member function if it exists.
Definition: Xml.h:1672
String getOptionalAttributeValue(const String &name, const String &def="") const
Get the value of an attribute as a string if the attribute is present in this element,...
Definition: Xml.h:1307
Element getRequiredElement(const String &tag)
Get a reference to a child element that must be present in this element.
void appendNode(Node node)
This is an abbreviation for insertNodeAfter(node_end(), node);.
Definition: Xml.h:1121
void getValueAs(T &out) const
Alternate form of getValueAs() that avoids unnecessary copying and heap allocation for reading in lar...
Definition: Xml.h:1212
attribute_iterator attribute_begin()
For iterating through all the attributes of this element.
Array_< Attribute > getAllAttributes()
Return an array containing Attribute handles referencing all the attributes of this element.
Definition: Xml.h:1345
Element getOptionalElement(const String &tag)
Get a reference to a child element that may be present in this element; otherwise return an invalid E...
bool isValueElement() const
Determine whether this element qualifies as a "value element", defined as an element containing zero ...
Element(const String &tagWord, const T &value, int precision)
Create a new value element and set its initial value to the text equivalent of any type T for which a...
Definition: Xml.h:1093
void insertNodeBefore(const node_iterator &pos, Node node)
Insert a node into the list of this Element's children, just before the node pointed to by the suppli...
static bool isA(const Node &)
Test whether a given Node is an element node.
Array_< Node > getAllNodes(NodeType allowed=AnyNodes)
Return an array containing Node handles referencing all the immediate child nodes contained in this e...
Definition: Xml.h:1403
const String & getRequiredAttributeValue(const String &name) const
Get the value of an attribute as a string and throw an error if that attribute is not present.
Definition: Xml.h:1287
attribute_iterator attribute_end() const
This attribute_end() iterator indicates the end of a sequence of attributes.
const String & getRequiredElementValue(const String &tag) const
Get the text value of a child value element that must be present in this element.
Definition: Xml.h:1223
void setElementTag(const String &tag)
Change the tag word that is used to bracket this element.
String & updValue()
Obtain a writable reference to the String containing the value of this value element.
node_iterator node_end() const
This node_end() iterator indicates the end of any sequence of nodes regardless of the NodeType restri...
element_iterator element_end() const
This element_end() iterator indicates the end of any sequence of elements regardless of the tag restr...
bool hasElement(const String &tag) const
Return true if this element has a child element with this tag.
Element clone() const
The clone() method makes a deep copy of this Element and its children and returns a new orphan Elemen...
static const Element & getAs(const Node &node)
Recast a Node to a const Element, throwing an error if the Node is not actually an element node.
void setValue(const String &value)
Set the text value of this value element.
void setAttributeValue(const String &name, const String &value)
Set the value of an attribute of this element, creating a new one if this is a new attribute name oth...
element_iterator element_begin(const String &tag="")
For iterating through the immediate child elements of this element, or the child elements that have t...
T getOptionalAttributeValueAs(const String &name, const T &def) const
Convert the value of an optional attribute, if present, from a string to the type of the template arg...
Definition: Xml.h:1323
void insertNodeAfter(const node_iterator &pos, Node node)
Insert a node into the list of this Element's children, just after the node pointed to by the supplie...
auto toXmlElementHelper(const T &thing, const std::string &name, int) -> Xml::Element
Helper function for toXmlElement() that selects the free function if no member function exists.
Definition: Xml.h:1681
node_iterator node_begin(NodeType allowed=AnyNodes)
For iterating through the immediate child nodes of this element, or the child nodes of the type(s) al...
Xml::Element toXmlElement(const T &thing, const std::string &name)
Default implementation of serialization to an XML element for objects whose class does not define a m...
Definition: Xml.h:1662
T getValueAs() const
Assuming this is a "value element", convert its text value to the type of the template argument T.
Definition: Xml.h:1207
const String & getValue() const
Get the text value of this value element.
Attribute getOptionalAttribute(const String &name)
Obtain an Attribute handle referencing a particular attribute of this element specified by name,...
auto fromXmlElementHelper(T &thing, Xml::Element &elt, const std::string &requiredTag, int) -> void
Helper function for fromXmlElement() that selects the free function if no member function exists.
Definition: Xml.h:1738
const String & getElementTag() const
Get the element tag word.
Element(const String &tagWord, const String &value="")
Create a value element that uses the given tag word but is not yet part of any XML document,...
bool hasAttribute(const String &name) const
Return true if this element has an attribute of this name.
void eraseNode(const node_iterator &deleteThis)
Delete the indicated node, which must be a child of this element, and must not be node_end().
T getRequiredAttributeValueAs(const String &name) const
Convert the text value of a required attribute to the type of the template argument T.
Definition: Xml.h:1297
Element()
Create an empty Element handle; this is suitable only for holding references to other Elements.
Definition: Xml.h:1055
static Element & getAs(Node &node)
Recast a writable Node to a writable Element, throwing an error if the Node is not actually an elemen...
Attribute getRequiredAttribute(const String &name)
Obtain an Attribute handle referencing a particular attribute of this element; an error will be throw...
void fromXmlElement(T &thing, Xml::Element &elt, const std::string &requiredName="")
Default implementation of deserialization from an XML element for objects whose class does not define...
Definition: Xml.h:1708
Element(const String &tagWord, const T &value)
Create a new value element and set its initial value to the text equivalent of any type T for which a...
Definition: Xml.h:1079
String getOptionalElementValue(const String &tag, const String &def="") const
Get the text value of a child value element that may be present in this element, otherwise return a d...
Definition: Xml.h:1230
bool hasNode(NodeType allowed=AnyNodes) const
See if this element has any child nodes, or any child nodes of the type(s) allowed by the NodeType fi...
Array_< Element > getAllElements(const String &tag="")
Return an array containing Element handles referencing all the immediate child elements contained in ...
Definition: Xml.h:1394
Node removeNode(const node_iterator &removeThis)
Remove the indicated node from this element without erasing it, returning it as an orphan Node.
Abstract handle for holding any kind of node in an XML tree.
Definition: Xml.h:747
bool isTopLevelNode() const
Return true if this Node is owned by the top-level Xml document, false if the Node is owned by an Ele...
bool isValid() const
Return true if this Node handle is referencing some node, false if the Node handle is empty.
Definition: Xml.h:801
Node(const Node &src)
Copy constructor is shallow; that is, this handle will refer to the same node as the source.
Definition: Xml.h:761
NodeType getNodeType() const
Get the Xml::NodeType of this node.
String getNodeTypeAsString() const
Get the Node type as a string; an empty handle returns "NoNode".
Node()
Create an empty Node handle that can be used to hold a reference to any kind of Node.
Definition: Xml.h:757
Node clone() const
The clone() method makes a deep copy of this Node and its children and returns a new orphan Node with...
std::ostream & operator<<(std::ostream &o, const Node &xmlNode)
Output a "pretty printed" textual representation of the given XML node (and all its contents) to an s...
Definition: Xml.h:895
bool isOrphan() const
Return true if this Node is an orphan, meaning that it is not empty, but is not owned by any element ...
Element getParentElement()
Return a handle referencing this node's parent if it has one, otherwise throws an error; check first ...
const String & getNodeText() const
Return a text value associated with this Node (not including its child nodes if any); the behavior de...
void writeToString(String &out, bool compact=false) const
Serialize this node (and everything it contains) to the given String.
Node & operator=(const Node &src)
Copy assignment is shallow; the handle is first cleared and then will refer to the same node as the s...
Definition: Xml.h:766
void clear()
This method restores the Node handle to its default-constructed state but does not recover any heap s...
bool operator==(const Node &other) const
Comparing Nodes for equality means asking if the two Node handles are referring to exactly the same o...
Definition: Xml.h:854
bool operator!=(const Node &other) const
Inequality test using same criteria as operator==().
Definition: Xml.h:856
~Node()
The Node handle destructor does not recover heap space so if you create orphan nodes and then don't p...
Definition: Xml.h:775
void clearOrphan()
This method explicitly frees the heap space for an orphan node that was created but never inserted in...
bool hasParentElement() const
Return true if this node has a parent, i.e.
This is the "leaf" content of an element.
Definition: Xml.h:1487
const String & getText() const
Obtain a const reference to the String holding the value of this Text.
static bool isA(const Node &)
Test whether a given Node is an Text node.
static Text & getAs(Node &node)
Recast a writable Node to a writable Text node, throwing an error if the Node is not actually a Text ...
String & updText()
Obtain a writable reference to the String holding the value of this Text node; this can be used to al...
Text clone() const
The clone() method makes a deep copy of this Text node and returns a new orphan Text node with the sa...
Text(const String &text)
Create a new Text node with the given text; the node is not yet owned by any XML document.
static const Text & getAs(const Node &node)
Recast a Node to a const Text node, throwing an error if the Node is not actually a Text node.
Text()
Create an empty Text node handle, suitable only for holding references to other Text nodes.
Definition: Xml.h:1491
This is something we don't understand but can carry around.
Definition: Xml.h:1582
void setContents(const String &contents)
Change the contents of this Unknown node.
static bool isA(const Node &)
Test whether a given Node is an Unknown node.
Unknown(const String &contents)
Create a new Unknown node with the given contents; the node is not yet owned by any XML document.
const String & getContents() const
Obtain the contents of this Unknown node.
static Unknown & getAs(Node &node)
Recast a writable Node to a writable Unknown, throwing an error if the Node is not actually an Unknow...
static const Unknown & getAs(const Node &node)
Recast a Node to a const Unknown, throwing an error if the Node is not actually an Unknown node.
Unknown(Element &element, const String &contents)
Create a new Unknown node and append it to the list of nodes that are children of the given Element.
Definition: Xml.h:1598
Unknown()
Create an empty Unknown node handle, suitable only for holding references to other Unknown nodes.
Definition: Xml.h:1586
Unknown clone() const
The clone() method makes a deep copy of this Unknown node and returns a new orphan Unknown node with ...
This is a bidirectional iterator suitable for moving forward or backward within a list of Attributes ...
Definition: Xml.h:649
attribute_iterator & operator--()
Prefix decrement operator moves the iterator to the previous attribute (or attribute_end() if it was ...
attribute_iterator(Attribute &attr)
Construct this iterator to point to the same attribute as does the supplied Attribute handle (or attr...
Definition: Xml.h:662
~attribute_iterator()
An iterator destructor never deletes the object to which it refers.
Definition: Xml.h:668
attribute_iterator & operator++()
Prefix increment operator advances the iterator to the next attribute (or attribute_end() if it was a...
Attribute & operator*() const
Return a writable reference to the Attribute referenced by this iterator; the handle will be invalid ...
Definition: Xml.h:695
std::bidirectional_iterator_tag iterator_category
Definition: Xml.h:651
std::ptrdiff_t difference_type
Definition: Xml.h:653
attribute_iterator()
Default constructor creates an iterator that compares equal to attribute_end().
Definition: Xml.h:659
attribute_iterator operator--(int)
Postfix decrement operator moves the iterator to the previous attribute (or attribute_end() if it was...
Attribute * operator->() const
Return a writable pointer to the Attribute referenced by this iterator; the pointer will never be nul...
Definition: Xml.h:699
attribute_iterator & operator=(const attribute_iterator &src)
Copy assignment takes an attribute_iterator that can be const, but that still allows writing to the A...
Definition: Xml.h:671
bool operator!=(const attribute_iterator &other) const
Uses same criteria as operator==().
Definition: Xml.h:707
bool operator==(const attribute_iterator &other) const
Comparison return true only if both iterators refer to the same in-memory attribute or both are at at...
Definition: Xml.h:704
attribute_iterator operator++(int)
Postfix increment operator advances the iterator to the next attribute (or attribute_end() if it was ...
attribute_iterator(const attribute_iterator &src)
Copy constructor takes an attribute_iterator that can be const, but that still allows writing to the ...
Definition: Xml.h:665
This is a bidirectional iterator suitable for moving forward or backward within a list of Element nod...
Definition: Xml.h:973
element_iterator & operator--()
element_iterator operator--(int)
element_iterator & operator++()
Element * operator->() const
Definition: Xml.h:1477
bool operator!=(const element_iterator &other) const
Definition: Xml.h:1003
element_iterator & operator=(const element_iterator &src)
Copy assignment takes an element_iterator that can be const, but that still allows writing to the Ele...
Definition: Xml.h:991
Element & operator*() const
Definition: Xml.h:1475
element_iterator operator++(int)
element_iterator(const element_iterator &src)
Copy constructor takes an element_iterator that can be const, but that still allows writing to the El...
Definition: Xml.h:986
bool operator==(const element_iterator &other) const
Definition: Xml.h:1001
element_iterator(const String &tag="")
This is the default constructor which leaves the element_iterator empty, and you can optionally set t...
Definition: Xml.h:978
This is a bidirectional iterator suitable for moving forward or backward within a list of Nodes,...
Definition: Xml.h:909
void reassign(TiXmlNode *tiNode)
Definition: Xml.h:950
node_iterator & operator=(const node_iterator &src)
Copy assignment takes an node_iterator that can be const, but that still allows writing to the Node.
Definition: Xml.h:930
node_iterator(Node &node, NodeType allowed=AnyNodes)
Definition: Xml.h:919
node_iterator & operator++()
bool operator!=(const node_iterator &other) const
Definition: Xml.h:944
node_iterator operator++(int)
node_iterator(const node_iterator &src)
Copy constructor takes a node_iterator that can be const, but that still allows writing to the Node.
Definition: Xml.h:924
Node * operator->()
Definition: Xml.h:938
Node * operator->() const
Definition: Xml.h:942
node_iterator(TiXmlNode *tiNode, NodeType allowed=AnyNodes)
Definition: Xml.h:948
Node & operator*()
Definition: Xml.h:937
std::ptrdiff_t difference_type
Definition: Xml.h:913
node_iterator(NodeType allowed=AnyNodes)
Definition: Xml.h:917
Node & operator*() const
Definition: Xml.h:941
bool operator==(const node_iterator &other) const
Definition: Xml.h:943
std::bidirectional_iterator_tag iterator_category
Definition: Xml.h:911
node_iterator & operator--()
~node_iterator()
An iterator destructor never deletes the object to which it refers.
Definition: Xml.h:927
node_iterator operator--(int)
friend class element_iterator
Definition: Xml.h:958
bool readUnformatted(std::istream &in, T &v)
The default implementation of readUnformatted<T> reads in the next whitespace-separated token and the...
Definition: Serialize.h:176
void writeUnformatted(std::ostream &o, const T &v)
The default implementation of writeUnformatted<T> converts the object to a String using the templatiz...
Definition: Serialize.h:76
NodeType
The Xml::NodeType enum serves as the actual type of a node and as a filter for allowable node types d...
Definition: Xml.h:72
@ NoNode
Type of empty Node handle, or null filter.
Definition: Xml.h:73
@ JunkNodes
Filter out meaningful nodes.
Definition: Xml.h:80
@ AnyNodes
Allow all nodes.
Definition: Xml.h:81
@ NoJunkNodes
Filter out meaningless nodes.
Definition: Xml.h:79
@ ElementNode
Element node type and only-Elements filter.
Definition: Xml.h:74
@ UnknownNode
Unknown node type and only-Unknowns filter.
Definition: Xml.h:77
@ CommentNode
Comment node type and only-Comments filter.
Definition: Xml.h:76
@ TextNode
Text node type and only-Text nodes filter.
Definition: Xml.h:75
String getNodeTypeAsString(NodeType type)
Translate a NodeType to a human-readable string.
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
Matrix_< E > operator*(const MatrixBase< E > &l, const typename CNT< E >::StdNumber &r)
Definition: BigMatrix.h:605
Obtain human-readable and XML-usable names for arbitrarily-complicated C++ types.
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:862