Simbody 3.9
Loading...
Searching...
No Matches
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
34namespace SimTK {
35
36// These are declared but never defined; all TinyXML code is hidden.
37class TiXmlNode;
38class TiXmlElement;
39class TiXmlAttribute;
40class TiXmlText;
41class TiXmlComment;
42class TiXmlUnknown;
43
45namespace Xml {
46
47// These classes are defined below.
48class Attribute;
49class Node; // This is the abstract handle type for any node.
50class Comment; // These are the concrete node types.
51class Unknown; // "
52class Text; // "
53class Element; // "
54
55// This provides iteration over all the attributes found in a given element.
56class 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.
60class 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.
65class element_iterator;
66
83
86
304//------------------------------------------------------------------------------
305// XML :: DOCUMENT
306//------------------------------------------------------------------------------
308public:
312
322
328explicit Document(const String& pathname);
329
332Document(const Document& source);
333
338
341
343void clear();
353void readFromFile(const String& pathname);
358void writeToFile(const String& pathname) const;
362void readFromString(const String& xmlDocument);
366void readFromString(const char* xmlDocument);
372void writeToString(String& xmlDocument, bool compact = false) const;
377void setIndentString(const String& indent);
380const String& getIndentString() const;
381
385static void setXmlCondenseWhiteSpace(bool shouldCondense);
400
413
416const String& getRootTag() const;
419void setRootTag(const String& tag);
420
429 Node insertThis);
433 Node insertThis);
439void eraseTopLevelNode(const node_iterator& deleteThis);
463
499
502void setXmlVersion(const String& version);
505void setXmlEncoding(const String& encoding);
510void setXmlIsStandalone(bool isStandalone);
513//------------------------------------------------------------------------------
514 private:
515friend class Node;
516
517class Impl; // a private, local class Document::Impl
518const Impl& getImpl() const {assert(impl); return *impl;}
519Impl& updImpl() {assert(impl); return *impl;}
520
521Document& unconst() const {return *const_cast<Document*>(this);}
522
523Impl* 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.
531inline 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//------------------------------------------------------------------------------
548public:
550Attribute() : tiAttr(0) {}
553Attribute(const String& name, const String& value);
557Attribute(const Attribute& src) : tiAttr(src.tiAttr) {}
563{ if (&src!=this) {clear(); tiAttr=src.tiAttr;} return *this; }
567~Attribute() {clear();}
569bool isValid() const {return tiAttr!=0;}
574bool isOrphan() const;
576const String& getName() const;
579const String& getValue() const;
586Attribute& setValue(const String& value);
587
591void clear();
596
601void writeToString(String& out) const;
602
606bool operator==(const Attribute& attr) const {return tiAttr==attr.tiAttr;}
607bool operator!=(const Attribute& attr) const {return tiAttr!=attr.tiAttr;}
608
609//------------------------------------------------------------------------------
610 private:
612friend class Element;
613
614explicit Attribute(TiXmlAttribute* attr) {tiAttr=attr;}
615const TiXmlAttribute& getTiAttr() const {assert(tiAttr);return *tiAttr;}
616TiXmlAttribute& 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.
622void setTiAttrPtr(TiXmlAttribute* attr) {tiAttr=attr;}
623const TiXmlAttribute* getTiAttrPtr() const {return tiAttr;}
624TiXmlAttribute* updTiAttrPtr() {return tiAttr;}
625
626Attribute& unconst() const {return *const_cast<Attribute*>(this);}
627
628TiXmlAttribute* 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.
636inline 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//------------------------------------------------------------------------------
650public:
651 using iterator_category = std::bidirectional_iterator_tag;
653 using difference_type = std::ptrdiff_t;
656
662explicit 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
695Attribute& operator*() const {return const_cast<Attribute&>(attr);}
699Attribute* operator->() const {return const_cast<Attribute*>(&attr);}
704bool operator==(const attribute_iterator& other) const
705{ return other.attr==attr; }
707bool operator!=(const attribute_iterator& other) const
708{ return other.attr!=attr; }
709
710//------------------------------------------------------------------------------
711 private:
712friend class Element;
713
714explicit attribute_iterator(TiXmlAttribute* ap) : attr(ap) {}
715
716Attribute attr; // the lone data member
717};
718
719
720
721//------------------------------------------------------------------------------
722// XML :: NODE
723//------------------------------------------------------------------------------
748public:
749
754
757Node() : tiNode(0) {}
761Node(const Node& src) : tiNode(src.tiNode) {}
766Node& operator=(const Node& src)
767{ if (&src!=this) {clear(); tiNode=src.tiNode;} return *this; }
771Node clone() const;
775~Node() {clear();}
779void clear();
791
795
798
801bool isValid() const {return tiNode != 0;}
802
806bool isTopLevelNode() const;
807
812bool isOrphan() const;
813
817bool hasParentElement() const;
818
829
840const String& getNodeText() const;
841
848void writeToString(String& out, bool compact=false) const;
854bool operator==(const Node& other) const {return other.tiNode==tiNode;}
856bool operator!=(const Node& other) const {return other.tiNode!=tiNode;}
857
858
859//------------------------------------------------------------------------------
860 protected:
// don't let Doxygen see these
862explicit Node(TiXmlNode* tiNode) : tiNode(tiNode) {}
863
864const TiXmlNode& getTiNode() const {assert(tiNode);return *tiNode;}
865TiXmlNode& 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.
870void setTiNodePtr(TiXmlNode* node) {tiNode=node;}
871const TiXmlNode* getTiNodePtr() const {return tiNode;}
872TiXmlNode* updTiNodePtr() {return tiNode;}
875//------------------------------------------------------------------------------
876 private:
877friend class Document;
878friend class node_iterator;
879friend class Comment;
880friend class Unknown;
881friend class Text;
882friend class Element;
883
884Node& unconst() const {return *const_cast<Node*>(this);}
885
886TiXmlNode* tiNode; // the lone data member
887};
888
894// Do this inline so we don't have to pass the ostream through the API.
895inline 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//------------------------------------------------------------------------------
910public:
911 using iterator_category = std::bidirectional_iterator_tag;
913 using difference_type = std::ptrdiff_t;
914 using pointer = Node*;
915 using reference = Node&;
916
917explicit node_iterator(NodeType allowed=AnyNodes)
918: allowed(allowed) {}
919explicit 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
934node_iterator operator++(int); // postfix
936node_iterator operator--(int); // postfix
937Node& operator*() {return node;}
938Node* 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.
941Node& operator*() const {return const_cast<Node&>(node);}
942Node* operator->() const {return const_cast<Node*>(&node);}
943bool operator==(const node_iterator& other) const {return other.node==node;}
944bool operator!=(const node_iterator& other) const {return other.node!=node;}
945
946//------------------------------------------------------------------------------
947 protected:
948explicit node_iterator(TiXmlNode* tiNode, NodeType allowed=AnyNodes)
949: node(tiNode), allowed(allowed) {}
950void reassign(TiXmlNode* tiNode)
951{ node.setTiNodePtr(tiNode); }
952
953//------------------------------------------------------------------------------
954 private:
955friend class Document;
956friend class Node;
957friend class Element;
958friend class element_iterator;
959
960Node node; // data members
961NodeType allowed;
962};
963
964
965
966//------------------------------------------------------------------------------
967// XML :: ELEMENT ITERATOR
968//------------------------------------------------------------------------------
974public:
975
978explicit element_iterator(const String& tag="")
979: node_iterator(ElementNode), tag(tag) {}
982inline 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
998inline Element& operator*() const; // below
999inline Element* operator->() const; // below
1000
1001bool operator==(const element_iterator& other) const
1002{ return other.upcast()==upcast();}
1003bool operator!=(const element_iterator& other) const
1004{ return other.upcast()!=upcast();}
1005
1006//------------------------------------------------------------------------------
1007 private:
1008friend class Element;
1009
1010explicit element_iterator(TiXmlElement* tiElt, const String& tag="")
1011: node_iterator((TiXmlNode*)tiElt, ElementNode), tag(tag) {}
1012void reassign(TiXmlElement* tiElt)
1013{ upcast().reassign((TiXmlNode*)tiElt); }
1014
1015const node_iterator& upcast() const
1016{ return *static_cast<const node_iterator*>(this); }
1017node_iterator& upcast()
1018{ return *static_cast<node_iterator*>(this); }
1019
1020String tag; // lone data member
1021};
1022
1023
1024
1025
1026//------------------------------------------------------------------------------
1027// XML :: ELEMENT
1028//------------------------------------------------------------------------------
1043public:
1044
1052
1056
1069explicit Element(const String& tagWord, const String& value="");
1070
1078template <class T>
1079Element(const String& tagWord, const T& value) :
1080 Element(tagWord, String(value)) { }
1081
1092template <class T>
1093Element(const String& tagWord, const T& value, int precision) :
1094 Element(tagWord, String(value, precision)) { }
1095
1100
1103const String& getElementTag() const;
1105void setElementTag(const String& tag);
1106
1112void insertNodeBefore(const node_iterator& pos, Node node);
1118void insertNodeAfter(const node_iterator& pos, Node node);
1119
1121void appendNode(Node node) {insertNodeAfter(node_end(), node);}
1122
1128void eraseNode(const node_iterator& deleteThis);
1134Node removeNode(const node_iterator& removeThis);
1148
1154bool isValueElement() const;
1155
1163const String& getValue() const;
1164
1171
1177void setValue(const String& value);
1178
1183template <class T>
1184void setValueAs(const T& value) {
1185 setValue(String(value));
1186}
1187
1195template <class T>
1196void setValueAs(const T& value, int precision) {
1197 // precision will be capped in the String constructor if needed.
1198 setValue(String(value, precision));
1199}
1200
1207template <class T> T getValueAs() const
1208{ T out; convertStringTo(getValue(),out); return out;}
1209
1212template <class T> void getValueAs(T& out) const
1213{ convertStringTo(getValue(),out); }
1214
1222const String&
1224{ return unconst().getRequiredElement(tag).getValue(); }
1225
1229String
1230getOptionalElementValue(const String& tag, const String& def="") const
1231{ const Element opt(unconst().getOptionalElement(tag));
1232 return opt.isValid() ? opt.getValue() : def; }
1233
1242template <class T> T
1244{ T out; convertStringTo(unconst().getRequiredElementValue(tag), out);
1245 return out; }
1246
1258template <class T> T
1259getOptionalElementValueAs(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; }
1272bool hasAttribute(const String& name) const;
1273
1276void setAttributeValue(const String& name, const String& value);
1277
1282void eraseAttribute(const String& name);
1283
1286const String&
1288{ return unconst().getRequiredAttribute(name).getValue(); }
1289
1296template <class T> T
1298{ T out; convertStringTo(getRequiredAttributeValue(name),out); return out; }
1299
1306String
1307getOptionalAttributeValue(const String& name, const String& def="") const
1308{ Attribute attr = unconst().getOptionalAttribute(name);
1309 if (!attr.isValid()) return def;
1310 return attr.getValue(); }
1311
1322template <class T> T
1323getOptionalAttributeValueAs(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
1371bool hasElement(const String& tag) const;
1374bool 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
1430static bool isA(const Node&);
1433static const Element& getAs(const Node& node);
1436static Element& getAs(Node& node);
1439//------------------------------------------------------------------------------
1440 private:
1441friend class Node;
1442friend class element_iterator;
1443
1444explicit Element(TiXmlElement* tiElt)
1445: Node(reinterpret_cast<TiXmlNode*>(tiElt)) {}
1446
1447TiXmlElement& updTiElement()
1448{ return reinterpret_cast<TiXmlElement&>(updTiNode()); }
1449const 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.
1455const TiXmlElement* getTiElementPtr() const
1456{ return reinterpret_cast<const TiXmlElement*>(getTiNodePtr()); }
1457TiXmlElement* updTiElementPtr()
1458{ return reinterpret_cast<TiXmlElement*>(updTiNodePtr()); }
1459void setTiElementPtr(TiXmlElement* elt)
1460{ setTiNodePtr(reinterpret_cast<TiXmlNode*>(elt)); }
1461
1462Element& 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//------------------------------------------------------------------------------
1488public:
1491Text() : Node() {}
1492
1495explicit Text(const String& text);
1496
1500Text clone() const;
1501
1504const String& getText() const;
1508
1514static bool isA(const Node&);
1517static const Text& getAs(const Node& node);
1520static Text& getAs(Node& node);
1523//------------------------------------------------------------------------------
1524 private:
1525// no data members; see Node
1526
1527explicit Text(TiXmlText* tiText)
1528: Node(reinterpret_cast<TiXmlNode*>(tiText)) {}
1529};
1530
1531
1532
1533//------------------------------------------------------------------------------
1534// XML :: COMMENT NODE
1535//------------------------------------------------------------------------------
1538public:
1542
1547explicit Comment(const String& text);
1548
1553
1559static bool isA(const Node&);
1562static const Comment& getAs(const Node& node);
1565static Comment& getAs(Node& node);
1568//------------------------------------------------------------------------------
1569 private:
1570// no data members; see Node
1571
1572explicit Comment(TiXmlComment* tiComment)
1573: Node(reinterpret_cast<TiXmlNode*>(tiComment)) {}
1574};
1575
1576
1577
1578//------------------------------------------------------------------------------
1579// XML :: UNKNOWN NODE
1580//------------------------------------------------------------------------------
1583public:
1587
1593explicit Unknown(const String& contents);
1594
1598Unknown(Element& element, const String& contents)
1599{ new(this) Unknown(contents);
1600 element.insertNodeBefore(element.node_end(), *this); }
1601
1606
1609const String& getContents() const;
1612void setContents(const String& contents);
1613
1619static bool isA(const Node&);
1622static const Unknown& getAs(const Node& node);
1625static Unknown& getAs(Node& node);
1628//------------------------------------------------------------------------------
1629 private:
1630// no data members; see Node
1631
1632explicit Unknown(TiXmlUnknown* tiUnknown)
1633: Node(reinterpret_cast<TiXmlNode*>(tiUnknown)) {}
1634};
1635
1636} // end of namespace Xml
1637
1638
1661template <class T> inline Xml::Element
1662toXmlElement(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
1671template <class T> inline
1672auto 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
1680template <class T> inline
1681auto toXmlElementHelper(const T& thing, const std::string& name, int)
1682 -> Xml::Element {
1683 return toXmlElement(thing, name); // call free function
1684}
1685
1707template <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
1727template <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
1737template <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
1759template <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
1776template <class T, class X>
1778 const std::string& name="") {
1779 return toXmlElement(static_cast<const ArrayViewConst_<T,X>&>(thing),name);
1780}
1781
1787template <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:64
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
const String & getValue() const
If this is a valid attribute handle, get the value of the attribute as a String, not including the qu...
const String & getName() const
If this is a valid attribute handle, get the name of the attribute.
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
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...
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.
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
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 & setValue(const String &value)
If this is a valid attribute handle, change its value to the given String which should not be quoted.
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.
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.
static Comment & getAs(Node &node)
Recast a writable Node to a writable Comment, throwing an error if the Node is not actually an Commen...
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,...
static void setXmlCondenseWhiteSpace(bool shouldCondense)
Set global mode to control whether white space is preserved or condensed down to a single space (affe...
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.
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".
Document & operator=(const Document &souce)
Copy assignment frees all heap space associated with the current Xml::Document and then makes a deep ...
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...
const String & getRootTag() const
Shortcut for getting the tag word of the root element which is usually the document type.
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.
const String & getIndentString() const
Return the current value of the indent string. The default is four spaces.
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
Array_< Element > getAllElements(const String &tag="")
Return an array containing Element handles referencing all the immediate child elements contained in ...
Definition Xml.h:1394
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.
String & updValue()
Obtain a writable reference to the String containing the value of this value element.
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
const String & getElementTag() const
Get the element tag word.
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...
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 & 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
static bool isA(const Node &)
Test whether a given Node is an element node.
attribute_iterator attribute_end() const
This attribute_end() iterator indicates the end of a sequence of attributes.
void setElementTag(const String &tag)
Change the tag word that is used to bracket this element.
node_iterator node_end() const
This node_end() iterator indicates the end of any sequence of nodes regardless of the NodeType restri...
Array_< Attribute > getAllAttributes()
Return an array containing Attribute handles referencing all the attributes of this element.
Definition Xml.h:1345
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...
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
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
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
const String & getValue() const
Get the text value of this value element.
Attribute getRequiredAttribute(const String &name)
Obtain an Attribute handle referencing a particular attribute of this element; an error will be throw...
static Element & getAs(Node &node)
Recast a writable Node to a writable Element, throwing an error if the Node is not actually an elemen...
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
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.
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...
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
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
const String & getNodeText() const
Return a text value associated with this Node (not including its child nodes if any); the behavior de...
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 ...
void writeToString(String &out, bool compact=false) const
Serialize this node (and everything it contains) to the given String.
void clear()
This method restores the Node handle to its default-constructed state but does not recover any heap s...
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
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
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 ...
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.
const String & getText() const
Obtain a const reference to the String holding the value of this Text.
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.
String & updText()
Obtain a writable reference to the String holding the value of this Text node; this can be used to al...
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
const String & getContents() const
Obtain the contents of this Unknown node.
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.
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
static Unknown & getAs(Node &node)
Recast a writable Node to a writable Unknown, throwing an error if the Node is not actually an Unknow...
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 & operator*() const
Return a writable reference to the Attribute referenced by this iterator; the handle will be invalid ...
Definition Xml.h:695
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 * 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()
An iterator destructor never deletes the object to which it refers.
Definition Xml.h:668
std::bidirectional_iterator_tag iterator_category
Definition Xml.h:651
std::ptrdiff_t difference_type
Definition Xml.h:653
attribute_iterator & operator--()
Prefix decrement operator moves the iterator to the previous attribute (or attribute_end() if it was ...
attribute_iterator & operator++()
Prefix increment operator advances the iterator to the next attribute (or attribute_end() if it was a...
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...
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 & 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
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=(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_iterator operator--(int)
Element * operator->() const
Definition Xml.h:1477
element_iterator & operator++()
bool operator!=(const element_iterator &other) const
Definition Xml.h:1003
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(Node &node, NodeType allowed=AnyNodes)
Definition Xml.h:919
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:937
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 & operator++()
node_iterator & operator--()
node_iterator(TiXmlNode *tiNode, NodeType allowed=AnyNodes)
Definition Xml.h:948
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()
An iterator destructor never deletes the object to which it refers.
Definition Xml.h:927
node_iterator operator--(int)
Node * operator->()
Definition Xml.h:938
friend class element_iterator
Definition Xml.h:958
Node * operator->() const
Definition Xml.h:942
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:881