Simbody  3.7
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 
321 Document();
322 
328 explicit Document(const String& pathname);
329 
332 Document(const Document& source);
333 
337 Document& operator=(const Document& souce);
338 
340 ~Document();
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);
388 static bool isXmlWhiteSpaceCondensed();
400 
412 Element getRootElement();
413 
416 const String& getRootTag() const;
419 void setRootTag(const String& tag);
420 
428 void insertTopLevelNodeAfter (const node_iterator& afterThis,
429  Node insertThis);
432 void insertTopLevelNodeBefore(const node_iterator& beforeThis,
433  Node insertThis);
439 void eraseTopLevelNode(const node_iterator& deleteThis);
446 Node removeTopLevelNode(const node_iterator& removeThis);
462 node_iterator node_begin(NodeType allowed=AnyNodes);
463 
466 node_iterator node_end() const;
489 String getXmlVersion() const;
492 String getXmlEncoding() const;
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 std::iterator<std::bidirectional_iterator_tag, Attribute> {
651 public:
657 explicit attribute_iterator(Attribute& attr) : attr(attr) {}
661 : attr(src->updTiAttrPtr()) {}
663 ~attribute_iterator() {attr.setTiAttrPtr(0);}
667 { attr.setTiAttrPtr(src->updTiAttrPtr()); return *this; }
671 attribute_iterator& operator++(); // prefix
675 attribute_iterator operator++(int); // postfix
679 attribute_iterator& operator--(); // prefix
683 attribute_iterator operator--(int); // postfix
684 
685 // It's the iterator that's const in these next two methods; it still points
686 // to a non-const object just like a char* const p.
687 
690 Attribute& operator*() const {return const_cast<Attribute&>(attr);}
694 Attribute* operator->() const {return const_cast<Attribute*>(&attr);}
699 bool operator==(const attribute_iterator& other) const
700 { return other.attr==attr; }
702 bool operator!=(const attribute_iterator& other) const
703 { return other.attr!=attr; }
704 
705 //------------------------------------------------------------------------------
706  private:
707 friend class Element;
708 
709 explicit attribute_iterator(TiXmlAttribute* ap) : attr(ap) {}
710 
711 Attribute attr; // the lone data member
712 };
713 
714 
715 
716 //------------------------------------------------------------------------------
717 // XML :: NODE
718 //------------------------------------------------------------------------------
743 public:
744 
749 
752 Node() : tiNode(0) {}
756 Node(const Node& src) : tiNode(src.tiNode) {}
761 Node& operator=(const Node& src)
762 { if (&src!=this) {clear(); tiNode=src.tiNode;} return *this; }
766 Node clone() const;
770 ~Node() {clear();}
774 void clear();
778 void clearOrphan();
786 
789 NodeType getNodeType() const;
790 
793 
796 bool isValid() const {return tiNode != 0;}
797 
801 bool isTopLevelNode() const;
802 
807 bool isOrphan() const;
808 
812 bool hasParentElement() const;
813 
816 Element getParentElement();
824 
835 const String& getNodeText() const;
836 
843 void writeToString(String& out, bool compact=false) const;
849 bool operator==(const Node& other) const {return other.tiNode==tiNode;}
851 bool operator!=(const Node& other) const {return other.tiNode!=tiNode;}
852 
853 
854 //------------------------------------------------------------------------------
855  protected: // don't let Doxygen see these
857 explicit Node(TiXmlNode* tiNode) : tiNode(tiNode) {}
858 
859 const TiXmlNode& getTiNode() const {assert(tiNode);return *tiNode;}
860 TiXmlNode& updTiNode() {assert(tiNode);return *tiNode;}
861 
862 // Careful: these "Ptr" methods provide raw access to the contained
863 // pointer without any cleanup or error checking. In particular,
864 // setTiNodePtr() does not attempt to delete the current contents.
865 void setTiNodePtr(TiXmlNode* node) {tiNode=node;}
866 const TiXmlNode* getTiNodePtr() const {return tiNode;}
867 TiXmlNode* updTiNodePtr() {return tiNode;}
870 //------------------------------------------------------------------------------
871  private:
872 friend class Document;
873 friend class node_iterator;
874 friend class Comment;
875 friend class Unknown;
876 friend class Text;
877 friend class Element;
878 
879 Node& unconst() const {return *const_cast<Node*>(this);}
880 
881 TiXmlNode* tiNode; // the lone data member
882 };
883 
889 // Do this inline so we don't have to pass the ostream through the API.
890 inline std::ostream& operator<<(std::ostream& o, const Node& xmlNode) {
891  String output;
892  xmlNode.writeToString(output);
893  return o << output;
894 }
895 
896 
897 
898 //------------------------------------------------------------------------------
899 // XML :: NODE ITERATOR
900 //------------------------------------------------------------------------------
905 : public std::iterator<std::bidirectional_iterator_tag, Node> {
906 public:
907 
908 explicit node_iterator(NodeType allowed=AnyNodes)
909 : allowed(allowed) {}
910 explicit node_iterator(Node& node, NodeType allowed=AnyNodes)
911 : node(node), allowed(allowed) {}
912 
916 : node(*src), allowed(src.allowed) {}
918 ~node_iterator() {node.setTiNodePtr(0);}
922 { node = *src; allowed = src.allowed; return *this; }
923 
924 node_iterator& operator++(); // prefix
925 node_iterator operator++(int); // postfix
926 node_iterator& operator--(); // prefix
927 node_iterator operator--(int); // postfix
928 Node& operator*() {return node;}
929 Node* operator->() {return &node;}
930 // It's the iterator that's const; it still points to a non-const object
931 // just like a char* const p.
932 Node& operator*() const {return const_cast<Node&>(node);}
933 Node* operator->() const {return const_cast<Node*>(&node);}
934 bool operator==(const node_iterator& other) const {return other.node==node;}
935 bool operator!=(const node_iterator& other) const {return other.node!=node;}
936 
937 //------------------------------------------------------------------------------
938  protected:
939 explicit node_iterator(TiXmlNode* tiNode, NodeType allowed=AnyNodes)
940 : node(tiNode), allowed(allowed) {}
941 void reassign(TiXmlNode* tiNode)
942 { node.setTiNodePtr(tiNode); }
943 
944 //------------------------------------------------------------------------------
945  private:
946 friend class Document;
947 friend class Node;
948 friend class Element;
949 friend class element_iterator;
950 
951 Node node; // data members
952 NodeType allowed;
953 };
954 
955 
956 
957 //------------------------------------------------------------------------------
958 // XML :: ELEMENT ITERATOR
959 //------------------------------------------------------------------------------
965 public:
966 
969 explicit element_iterator(const String& tag="")
970 : node_iterator(ElementNode), tag(tag) {}
973 inline explicit element_iterator(Element& elt, const String& tag=""); // below
974 
978 : node_iterator(src), tag(src.tag) {}
979 
983 { upcast()=src; tag = src.tag; return *this; }
984 
985 element_iterator& operator++(); // prefix
986 element_iterator operator++(int); // postfix
987 element_iterator& operator--(); // prefix
988 element_iterator operator--(int); // postfix
989 inline Element& operator*() const; // below
990 inline Element* operator->() const; // below
991 
992 bool operator==(const element_iterator& other) const
993 { return other.upcast()==upcast();}
994 bool operator!=(const element_iterator& other) const
995 { return other.upcast()!=upcast();}
996 
997 //------------------------------------------------------------------------------
998  private:
999 friend class Element;
1000 
1001 explicit element_iterator(TiXmlElement* tiElt, const String& tag="")
1002 : node_iterator((TiXmlNode*)tiElt, ElementNode), tag(tag) {}
1003 void reassign(TiXmlElement* tiElt)
1004 { upcast().reassign((TiXmlNode*)tiElt); }
1005 
1006 const node_iterator& upcast() const
1007 { return *static_cast<const node_iterator*>(this); }
1008 node_iterator& upcast()
1009 { return *static_cast<node_iterator*>(this); }
1010 
1011 String tag; // lone data member
1012 };
1013 
1014 
1015 
1016 
1017 //------------------------------------------------------------------------------
1018 // XML :: ELEMENT
1019 //------------------------------------------------------------------------------
1034 public:
1035 
1043 
1046 Element() : Node() {}
1047 
1060 explicit Element(const String& tagWord, const String& value="");
1061 
1067 template <class T>
1068 Element(const String& tagWord, const T& value)
1069 { new(this) Element(tagWord, String(value)); }
1070 
1074 Element clone() const;
1075 
1078 const String& getElementTag() const;
1080 void setElementTag(const String& tag);
1081 
1087 void insertNodeBefore(const node_iterator& pos, Node node);
1093 void insertNodeAfter(const node_iterator& pos, Node node);
1094 
1096 void appendNode(Node node) {insertNodeAfter(node_end(), node);}
1097 
1103 void eraseNode(const node_iterator& deleteThis);
1109 Node removeNode(const node_iterator& removeThis);
1123 
1129 bool isValueElement() const;
1130 
1138 const String& getValue() const;
1139 
1145 String& updValue();
1146 
1152 void setValue(const String& value);
1153 
1157 template <class T>
1158 void setValueAs(const T& value)
1159 { setValue(String(value)); }
1160 
1167 template <class T> T getValueAs() const
1168 { T out; convertStringTo(getValue(),out); return out;}
1169 
1172 template <class T> void getValueAs(T& out) const
1173 { convertStringTo(getValue(),out); }
1174 
1182 const String&
1184 { return unconst().getRequiredElement(tag).getValue(); }
1185 
1189 String
1190 getOptionalElementValue(const String& tag, const String& def="") const
1191 { const Element opt(unconst().getOptionalElement(tag));
1192  return opt.isValid() ? opt.getValue() : def; }
1193 
1202 template <class T> T
1204 { T out; convertStringTo(unconst().getRequiredElementValue(tag), out);
1205  return out; }
1206 
1218 template <class T> T
1219 getOptionalElementValueAs(const String& tag, const T& def) const
1220 { const Element opt(unconst().getOptionalElement(tag));
1221  if (!opt.isValid()) return def;
1222  T out; convertStringTo(opt.getValue(), out); return out; }
1232 bool hasAttribute(const String& name) const;
1233 
1236 void setAttributeValue(const String& name, const String& value);
1237 
1242 void eraseAttribute(const String& name);
1243 
1246 const String&
1248 { return unconst().getRequiredAttribute(name).getValue(); }
1249 
1256 template <class T> T
1258 { T out; convertStringTo(getRequiredAttributeValue(name),out); return out; }
1259 
1266 String
1267 getOptionalAttributeValue(const String& name, const String& def="") const
1268 { Attribute attr = unconst().getOptionalAttribute(name);
1269  if (!attr.isValid()) return def;
1270  return attr.getValue(); }
1271 
1282 template <class T> T
1283 getOptionalAttributeValueAs(const String& name, const T& def) const
1284 { Attribute attr = unconst().getOptionalAttribute(name);
1285  if (!attr.isValid()) return def;
1286  T out; convertStringTo(attr.getValue(), out); return out; }
1287 
1290 Attribute getRequiredAttribute(const String& name);
1291 
1295 Attribute getOptionalAttribute(const String& name);
1296 
1306 { return Array_<Attribute>(attribute_begin(), attribute_end()); }
1307 
1308 
1312 attribute_iterator attribute_begin();
1315 attribute_iterator attribute_end() const;
1329 
1331 bool hasElement(const String& tag) const;
1334 bool hasNode(NodeType allowed=AnyNodes) const;
1335 
1340 Element getRequiredElement(const String& tag);
1341 
1345 Element getOptionalElement(const String& tag);
1346 
1355 { return Array_<Element>(element_begin(tag), element_end()); }
1356 
1364 { return Array_<Node>(node_begin(allowed), node_end()); }
1365 
1370 element_iterator element_begin(const String& tag="");
1373 element_iterator element_end() const;
1374 
1379 node_iterator node_begin(NodeType allowed=AnyNodes);
1382 node_iterator node_end() const;
1390 static bool isA(const Node&);
1393 static const Element& getAs(const Node& node);
1396 static Element& getAs(Node& node);
1399 //------------------------------------------------------------------------------
1400  private:
1401 friend class Node;
1402 friend class element_iterator;
1403 
1404 explicit Element(TiXmlElement* tiElt)
1405 : Node(reinterpret_cast<TiXmlNode*>(tiElt)) {}
1406 
1407 TiXmlElement& updTiElement()
1408 { return reinterpret_cast<TiXmlElement&>(updTiNode()); }
1409 const TiXmlElement& getTiElement() const
1410 { return reinterpret_cast<const TiXmlElement&>(getTiNode()); }
1411 
1412 // Careful: these "Ptr" methods provide raw access to the contained
1413 // pointer without any cleanup or error checking. In particular,
1414 // setTiElementPtr() does not attempt to delete the current contents.
1415 const TiXmlElement* getTiElementPtr() const
1416 { return reinterpret_cast<const TiXmlElement*>(getTiNodePtr()); }
1417 TiXmlElement* updTiElementPtr()
1418 { return reinterpret_cast<TiXmlElement*>(updTiNodePtr()); }
1419 void setTiElementPtr(TiXmlElement* elt)
1420 { setTiNodePtr(reinterpret_cast<TiXmlNode*>(elt)); }
1421 
1422 Element& unconst() const {return *const_cast<Element*>(this);}
1423 
1424 
1425 // no data members; see Node
1426 };
1427 
1428 
1429 
1430 // A few element_iterator inline definitions had to wait for Element to be
1431 // defined.
1433  (Element& elt, const String& tag)
1434 : node_iterator(elt, ElementNode), tag(tag) {}
1436 { return Element::getAs(*upcast());}
1438 { return &Element::getAs(*upcast());}
1439 
1440 
1441 
1442 
1443 //------------------------------------------------------------------------------
1444 // XML :: TEXT NODE
1445 //------------------------------------------------------------------------------
1448 public:
1451 Text() : Node() {}
1452 
1455 explicit Text(const String& text);
1456 
1460 Text clone() const;
1461 
1464 const String& getText() const;
1467 String& updText();
1468 
1474 static bool isA(const Node&);
1477 static const Text& getAs(const Node& node);
1480 static Text& getAs(Node& node);
1483 //------------------------------------------------------------------------------
1484  private:
1485 // no data members; see Node
1486 
1487 explicit Text(TiXmlText* tiText)
1488 : Node(reinterpret_cast<TiXmlNode*>(tiText)) {}
1489 };
1490 
1491 
1492 
1493 //------------------------------------------------------------------------------
1494 // XML :: COMMENT NODE
1495 //------------------------------------------------------------------------------
1498 public:
1501 Comment() : Node() {}
1502 
1507 explicit Comment(const String& text);
1508 
1512 Comment clone() const;
1513 
1519 static bool isA(const Node&);
1522 static const Comment& getAs(const Node& node);
1525 static Comment& getAs(Node& node);
1528 //------------------------------------------------------------------------------
1529  private:
1530 // no data members; see Node
1531 
1532 explicit Comment(TiXmlComment* tiComment)
1533 : Node(reinterpret_cast<TiXmlNode*>(tiComment)) {}
1534 };
1535 
1536 
1537 
1538 //------------------------------------------------------------------------------
1539 // XML :: UNKNOWN NODE
1540 //------------------------------------------------------------------------------
1543 public:
1546 Unknown() : Node() {}
1547 
1553 explicit Unknown(const String& contents);
1554 
1558 Unknown(Element& element, const String& contents)
1559 { new(this) Unknown(contents);
1560  element.insertNodeBefore(element.node_end(), *this); }
1561 
1565 Unknown clone() const;
1566 
1569 const String& getContents() const;
1572 void setContents(const String& contents);
1573 
1579 static bool isA(const Node&);
1582 static const Unknown& getAs(const Node& node);
1585 static Unknown& getAs(Node& node);
1588 //------------------------------------------------------------------------------
1589  private:
1590 // no data members; see Node
1591 
1592 explicit Unknown(TiXmlUnknown* tiUnknown)
1593 : Node(reinterpret_cast<TiXmlNode*>(tiUnknown)) {}
1594 };
1595 
1596 } // end of namespace Xml
1597 
1598 
1621 template <class T> inline Xml::Element
1622 toXmlElement(const T& thing, const std::string& name) {
1623  std::ostringstream os;
1624  writeUnformatted(os, thing);
1625  return Xml::Element(name.empty()?"value":name, os.str());
1626 }
1627 
1631 template <class T> inline
1632 auto toXmlElementHelper(const T& thing, const std::string& name, bool)
1633  -> decltype(std::declval<T>().toXmlElement(name)) {
1634  return thing.toXmlElement(name); // call member function
1635 }
1636 
1640 template <class T> inline
1641 auto toXmlElementHelper(const T& thing, const std::string& name, int)
1642  -> Xml::Element {
1643  return toXmlElement(thing, name); // call free function
1644 }
1645 
1667 template <class T> inline void
1669  const std::string& requiredName="") {
1670  if (!requiredName.empty()) {
1671  const String& name = elt.getElementTag();
1672  SimTK_ERRCHK2_ALWAYS(name==requiredName, "fromXmlElement<T>",
1673  "Expected element name '%s' but got '%s'.", requiredName.c_str(),
1674  name.c_str());
1675  }
1676  std::istringstream is(elt.getValue());
1677  const bool readOK = readUnformatted(is, thing);
1678  SimTK_ERRCHK2_ALWAYS(readOK, "fromXmlElement<T>",
1679  "Failed to read an object of type T='%s' from element value '%s' "
1680  "using readUnformatted<T>().",
1681  NiceTypeName<T>::namestr().c_str(), elt.getValue().c_str());
1682 }
1683 
1687 template <class T> inline
1688 auto fromXmlElementHelper(T& thing, Xml::Element& elt,
1689  const std::string& requiredTag, bool)
1690  -> decltype(std::declval<T>().fromXmlElement(elt,requiredTag)) {
1691  return thing.fromXmlElement(elt,requiredTag); // call member function
1692 }
1693 
1697 template <class T> inline
1698 auto fromXmlElementHelper(T& thing, Xml::Element& elt,
1699  const std::string& requiredTag, int)
1700  -> void {
1701  fromXmlElement(thing, elt, requiredTag); // call free function
1702 }
1703 
1704 
1705 // Definition of these functions (which should really be methods of
1706 // the Array_ classes) has to wait until Xml classes are declared because Xml
1707 // uses Array_.
1708 
1719 template <class T, class X>
1721  const std::string& name="") {
1722  static const int version = 1;
1723  Xml::Element e("Array");
1724  if (!name.empty()) e.setAttributeValue("name", name);
1725  e.setAttributeValue("version", String(version));
1726  for (const auto& v : thing)
1727  e.appendNode(toXmlElementHelper(v, "", true));
1728  return e;
1729 }
1730 
1736 template <class T, class X>
1738  const std::string& name="") {
1739  return toXmlElement(static_cast<const ArrayViewConst_<T,X>&>(thing),name);
1740 }
1741 
1747 template <class T, class X>
1749  const std::string& name="") {
1750  return toXmlElement(static_cast<const ArrayViewConst_<T,X>&>(thing),name);
1751 }
1752 
1753 } // namespace SimTK
1754 
1755 #endif // SimTK_SimTKCOMMON_XML_H_
1756 
1757 
void writeToString(String &xmlDocument, bool compact=false) const
Write the contents of this in-memory Xml::Document to the supplied string.
Unknown()
Create an empty Unknown node handle, suitable only for holding references to other Unknown nodes...
Definition: Xml.h:1546
Unknown node type and only-Unknowns filter.
Definition: Xml.h:77
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:849
This Array_ helper class is the base class for Array_, extending ArrayViewConst_ to add the ability t...
Definition: Array.h:52
bool operator!=(const Node &other) const
Inequality test using same criteria as operator==().
Definition: Xml.h:851
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
node_iterator(TiXmlNode *tiNode, NodeType allowed=AnyNodes)
Definition: Xml.h:939
#define SimTK_SimTKCOMMON_EXPORT
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:224
#define SimTK_ERRCHK2_ALWAYS(cond, whereChecked, fmt, a1, a2)
Definition: ExceptionMacros.h:289
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:1622
~Attribute()
The Attribute handle destructor does not recover heap space so if you create orphan attributes and th...
Definition: Xml.h:567
String getNodeTypeAsString(NodeType type)
Translate a NodeType to a human-readable string.
This is something we don&#39;t understand but can carry around.
Definition: Xml.h:1542
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:1698
Array_< Attribute > getAllAttributes()
Return an array containing Attribute handles referencing all the attributes of this element...
Definition: Xml.h:1305
Text()
Create an empty Text node handle, suitable only for holding references to other Text nodes...
Definition: Xml.h:1451
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:921
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:1247
const String & getValue() const
If this is a valid attribute handle, get the value of the attribute as a String, not including the qu...
Attribute & operator*() const
Return a writable reference to the Attribute referenced by this iterator; the handle will be invalid ...
Definition: Xml.h:690
const String & getElementTag() const
Get the element tag word.
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:1190
bool operator!=(const node_iterator &other) const
Definition: Xml.h:935
Node & operator*() const
Definition: Xml.h:932
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:1068
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
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
Node()
Create an empty Node handle that can be used to hold a reference to any kind of Node.
Definition: Xml.h:752
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:1641
node_iterator(NodeType allowed=AnyNodes)
Definition: Xml.h:908
void reassign(TiXmlNode *tiNode)
Definition: Xml.h:941
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
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:915
~Node()
The Node handle destructor does not recover heap space so if you create orphan nodes and then don&#39;t p...
Definition: Xml.h:770
Text node type and only-Text nodes filter.
Definition: Xml.h:75
bool isValid() const
Is this handle currently holding an attribute?
Definition: Xml.h:569
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:1363
Comment node type and only-Comments filter.
Definition: Xml.h:76
Node * operator->()
Definition: Xml.h:929
Element * operator->() const
Definition: Xml.h:1437
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...
attribute_iterator()
Default constructor creates an iterator that compares equal to attribute_end().
Definition: Xml.h:654
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:982
T getValueAs() const
Assuming this is a "value element", convert its text value to the type of the template argument T...
Definition: Xml.h:1167
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:1668
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:969
This file defines the Array_<T,X> class and related support classes including base classes ArrayViewC...
Type of empty Node handle, or null filter.
Definition: Xml.h:73
bool operator==(const node_iterator &other) const
Definition: Xml.h:934
bool operator!=(const attribute_iterator &other) const
Uses same criteria as operator==().
Definition: Xml.h:702
This is a bidirectional iterator suitable for moving forward or backward within a list of Attributes ...
Definition: Xml.h:649
Allow all nodes.
Definition: Xml.h:81
Element()
Create an empty Element handle; this is suitable only for holding references to other Elements...
Definition: Xml.h:1046
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:1688
This is the "leaf" content of an element.
Definition: Xml.h:1447
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
Element & operator*() const
Definition: Xml.h:1435
bool isValid() const
Return true if this Node handle is referencing some node, false if the Node handle is empty...
Definition: Xml.h:796
Node(const Node &src)
Copy constructor is shallow; that is, this handle will refer to the same node as the source...
Definition: Xml.h:756
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
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
An element has (1) a tagword, (2) a map of (name,value) pairs called attributes, and (3) a list of ch...
Definition: Xml.h:1033
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:890
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
void appendNode(Node node)
This is an abbreviation for insertNodeAfter(node_end(), node);.
Definition: Xml.h:1096
Attribute()
Default constructor creates a null Attribute handle.
Definition: Xml.h:550
Matrix_< E > operator*(const MatrixBase< E > &l, const typename CNT< E >::StdNumber &r)
Definition: BigMatrix.h:605
The Array_<T> container class is a plug-compatible replacement for the C++ standard template library ...
Definition: Array.h:53
void writeToString(String &out, bool compact=false) const
Serialize this node (and everything it contains) to the given String.
Xml::Element toXmlElement(const Array_< T, X > &thing, const std::string &name="")
Partial specialization for XML serialization of Array_ objects.
Definition: Xml.h:1748
~node_iterator()
An iterator destructor never deletes the object to which it refers.
Definition: Xml.h:918
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:1158
node_iterator node_end() const
This node_end() iterator indicates the end of any sequence of nodes regardless of the NodeType restri...
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...
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:1632
Xml::Element toXmlElement(const ArrayView_< T, X > &thing, const std::string &name="")
Partial specialization for XML serialization of ArrayView_ objects.
Definition: Xml.h:1737
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:699
void getValueAs(T &out) const
Alternate form of getValueAs() that avoids unnecessary copying and heap allocation for reading in lar...
Definition: Xml.h:1172
const String & getValue() const
Get the text value of this value element.
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:666
Array_< Element > getAllElements(const String &tag="")
Return an array containing Element handles referencing all the immediate child elements contained in ...
Definition: Xml.h:1354
attribute_iterator(Attribute &attr)
Construct this iterator to point to the same attribute as does the supplied Attribute handle (or attr...
Definition: Xml.h:657
This Array_ helper class is the base class for ArrayView_ which is the base class for Array_; here we...
Definition: Array.h:51
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:977
SimTK::String is a plug-compatible std::string replacement (plus some additional functionality) inten...
Definition: String.h:62
This is a bidirectional iterator suitable for moving forward or backward within a list of Nodes...
Definition: Xml.h:904
node_iterator(Node &node, NodeType allowed=AnyNodes)
Definition: Xml.h:910
Mandatory first inclusion for any Simbody source or header file.
Xml::Element toXmlElement(const ArrayViewConst_< T, X > &thing, const std::string &name="")
Partial specialization for XML serialization of ArrayViewConst_ objects.
Definition: Xml.h:1720
Element node type and only-Elements filter.
Definition: Xml.h:74
Node * operator->() const
Definition: Xml.h:933
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:1558
Obtain human-readable and XML-usable names for arbitrarily-complicated C++ types. ...
Definition: SimTKcommon/include/SimTKcommon/internal/common.h:858
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:1203
Abstract handle for holding any kind of node in an XML tree.
Definition: Xml.h:742
bool operator==(const element_iterator &other) const
Definition: Xml.h:992
Attribute * operator->() const
Return a writable pointer to the Attribute referenced by this iterator; the pointer will never be nul...
Definition: Xml.h:694
Comment()
Create an empty Comment node handle, suitable only for holding references to other Comment nodes...
Definition: Xml.h:1501
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, otherwise return a supplied default value.
Definition: Xml.h:1267
Filter out meaningless nodes.
Definition: Xml.h:79
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:761
A comment contains only uninterpreted text.
Definition: Xml.h:1497
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:1219
This is a bidirectional iterator suitable for moving forward or backward within a list of Element nod...
Definition: Xml.h:964
~attribute_iterator()
An iterator destructor never deletes the object to which it refers.
Definition: Xml.h:663
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:660
Node & operator*()
Definition: Xml.h:928
Elements can have attributes, which are name="value" pairs that appear within the element start tag i...
Definition: Xml.h:547
Filter out meaningful nodes.
Definition: Xml.h:80
bool operator!=(const Attribute &attr) const
Definition: Xml.h:607
void insertNodeBefore(const node_iterator &pos, Node node)
Insert a node into the list of this Element&#39;s children, just before the node pointed to by the suppli...
void writeToString(String &out) const
Serialize this attribute to the given String.
bool operator!=(const element_iterator &other) const
Definition: Xml.h:994
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
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:1183
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:1283
This class provides a minimalist capability for reading and writing XML documents, as files or strings.
Definition: Xml.h:307
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:1257