2 #include <xercesc/parsers/XercesDOMParser.hpp>
3 #include <xercesc/util/BinInputStream.hpp>
4 #include <xercesc/sax/InputSource.hpp>
11 class IStreamInputSource :
public xercesc::InputSource {
14 xercesc::BinInputStream* makeStream()
const {
15 return new IStreamBinInputStream(is);
18 class IStreamBinInputStream :
public xercesc::BinInputStream {
21 IStreamBinInputStream(std::istream &is) : xercesc::BinInputStream(), is(is) {};
22 XMLFilePos curPos(
void)
const {
return (XMLFilePos)is.tellg(); };
23 XMLSize_t readBytes(XMLByte*
const buf,
const XMLSize_t max) {
24 is.read((
char*)buf, (std::streamsize)max);
25 return (XMLSize_t)is.gcount();
27 const XMLCh* getContentType()
const {
33 IStreamInputSource(std::istream &is) : InputSource(), is(is) {};
39 throw std::runtime_error(
"Failed to transcode XML string");
41 std::string result(cStr);
42 xercesc::XMLString::release(&cStr);
48 xercesc::XMLPlatformUtils::Initialize();
49 std::unique_ptr<xercesc::XercesDOMParser> parser = std::make_unique<xercesc::XercesDOMParser>();
50 parser->setDoNamespaces(
true);
51 parser->parse(IStreamInputSource(xmlStream));
53 xercesc::DOMDocument* document = parser->getDocument();
56 xercesc::XMLPlatformUtils::Terminate();
57 throw std::runtime_error(
"Failed to parse XML");
60 xercesc::DOMElement* rootElement = document->getDocumentElement();
63 xercesc::XMLPlatformUtils::Terminate();
64 throw std::runtime_error(
"Failed to get root element of XML");
67 std::string rootName =
transcode(rootElement->getLocalName());
70 xercesc::XMLPlatformUtils::Terminate();
76 std::istringstream iss(xmlString);
82 xercesc::XMLPlatformUtils::Initialize();
83 std::unique_ptr<xercesc::XercesDOMParser> parser = std::make_unique<xercesc::XercesDOMParser>();
84 parser->setDoNamespaces(
true);
86 parser->parse(xmlFilename);
87 xercesc::XMLString::release(&xmlFilename);
90 xercesc::DOMDocument* document = parser->getDocument();
93 xercesc::XMLPlatformUtils::Terminate();
94 throw std::runtime_error(
"Failed to load and parse XML-file");
97 xercesc::DOMElement* rootElement = document->getDocumentElement();
100 xercesc::XMLPlatformUtils::Terminate();
101 throw std::runtime_error(
"Failed to get root element of XML");
104 std::string rootName =
transcode(rootElement->getLocalName());
108 xercesc::XMLPlatformUtils::Terminate();
120 return createInstance<XMLObject>(
xmlns,
"XMLObject", element);
129 xercesc::DOMNamedNodeMap* elementAttributes = element->getAttributes();
130 for (XMLSize_t i = 0; i < elementAttributes->getLength(); i++) {
131 xercesc::DOMNode* item = elementAttributes->item(i);
138 attributes.push_back( { attributeXmlns, attributePrefix, attributeName, attributeValue } );
142 for (
auto& defaultAttribute : defaultAttributes ) {
149 for (xercesc::DOMElement *childElement = element->getFirstElementChild(); childElement; childElement = childElement->getNextElementSibling()) {
165 throw std::runtime_error(
"Failed to get required child of element '" +
elementName +
"'");
178 std::vector< std::reference_wrapper<XMLObject> > result;
181 result.push_back(*child);
189 [attributeName](
Attribute& attribute) { return attribute.name == attributeName; }
194 throw std::runtime_error(
"Failed to get required attribute '" + attributeName +
"' of element '" +
elementName +
"'");
199 [attributeName](
Attribute& attribute) { return attribute.name == attributeName; }
210 xmlString += std::string(
" ") + (!attribute.prefix.empty() ? attribute.prefix +
":" :
"") + attribute.name +
"=\"" + attribute.value.value +
"\"";
215 xmlString += child->stringify();
224 auto indent = [&indentation](
unsigned int n) -> std::string {
226 for (
unsigned int i = 0; i < n; ++i) {
227 result += indentation;
232 std::string xmlString = indent(depth) + std::string(
"<") + (!
prefix.empty() ?
prefix +
":" :
"") +
elementName;
234 xmlString += std::string(
" ") + (!attribute.prefix.empty() ? attribute.prefix +
":" :
"") + attribute.name +
"=\"" + attribute.value.value +
"\"";
239 xmlString += child->format(indentation, depth+1);
A class representing a node in an XML-tree.
static XMLObject * createFromFile(const std::string &filename)
Create an XMLObject from an XML file.
static XMLObject * createFromString(const std::string &xmlString)
Create an XMLObject from a string representation of XML.
static XMLObject * createObject(const xercesc::DOMElement *element)
std::optional< std::reference_wrapper< Attribute > > getOptionalAttributeByName(const AttributeName &attributeName)
Get an optional attribute with the specified attribute name.
std::string format(std::string indentation="\t", unsigned int depth=0) const
Creates formated string representing the XMLObject including its children.
Children children
Child nodes of the XML element.
XMLObject & getRequiredChildByName(const ElementName &elementName)
Get a required child with the specified element name.
TextContent textContent
Textual content of XML element without children.
std::string stringify() const
Convert the XMLObject and its children to a string representation.
std::vector< std::reference_wrapper< XMLObject > > getChildrenByName(const ElementName &elementName)
Get all children with the specified element name.
XMLObject(const Namespace &xmlns, const ClassName &className, const xercesc::DOMElement *element, const Attributes &defaultAttributes)
static XMLObject * createFromStream(std::istream &xmlStream)
Create an XMLObject from the input stream.
std::optional< std::reference_wrapper< XMLObject > > getOptionalChildByName(const ElementName &elementName)
Get the optional child with the specified element name.
Attribute & getRequiredAttributeByName(const AttributeName &attributeName)
Get a required attribute with the specified attribute name.
The XML namespace contains classes representing XML-nodes defined in given XML-schema(s).
std::ostream & operator<<(std::ostream &os, const XMLObject *obj)
Allows printing of stringified XML object.
std::vector< Attribute > Attributes
std::string AttributeName
std::string transcode(const XMLCh *xmlChStr)
A struct representing an attribute of an XML-node.
A struct representing the value of an XML-node attribute.