8#include <xercesc/dom/DOMElement.hpp>
9#include <xercesc/dom/DOMNodeList.hpp>
10#include <xercesc/dom/DOMCharacterData.hpp>
11#include <xercesc/dom/DOMNamedNodeMap.hpp>
12#include <xercesc/dom/DOMDocument.hpp>
13#include <xercesc/dom/DOMException.hpp>
14#include <xercesc/dom/DOMTreeWalker.hpp>
15#include <xercesc/util/TransService.hpp>
16#include <xercesc/util/XMLString.hpp>
17#include <xercesc/util/PlatformUtils.hpp>
32 XERCES_CPP_NAMESPACE_USE
34 DOMTreeWalker* makeWalker(
const DOMNode* node) {
36 DOMDocument* doc = node->getOwnerDocument();
37 unsigned long whatToShow = DOMNodeFilter::SHOW_ELEMENT;
40 DOMNode* casted =
const_cast<DOMNode*
>(node);
42 DOMTreeWalker* walk = doc->createTreeWalker(casted, whatToShow, 0, expand);
49 XERCES_CPP_NAMESPACE_USE
51 XMLLCPTranscoder* Dom::transcoder = 0;
52 char* Dom::transBuf = 0;
54 unsigned int Dom::transBufSize = 1000;
55 XMLCh* Dom::xmlchBuf = 0;
57 unsigned int Dom::xmlchBufSize = 200;
58 XMLCh* Dom::xmlchStar = 0;
61 const char*
const name) {
63 if (!xmlchStar) xmlchStar = XMLString::transcode(
"*");
65 throw NullNode(
"from xmlBase::Dom::findFirstChildByName. Null parent arg.");
68 XMLCh* xmlchName = XMLString::transcode(name);
70 DOMTreeWalker* walk = makeWalker(parent);
71 DOMElement* child =
static_cast<DOMElement*
>(walk->firstChild());
72 if (XMLString::equals(xmlchName, xmlchStar))
return child;
76 while (! XMLString::equals(child->getNodeName(), xmlchName)) {
77 child =
static_cast<DOMElement*
>(walk->nextSibling());
82 XMLString::release(&xmlchName);
89 const std::string name) {
98 throw NullNode(
"from xmlBase::Dom::getSiblingElement. Null argument");
101 DOMNode* sib = child->getNextSibling();
104 if (sib->getNodeType() == DOMNode::ELEMENT_NODE) {
105 DOMElement* eltSib =
static_cast<DOMElement*
> (sib);
109 sib = sib->getNextSibling();
116 const DOMElement* elt =
static_cast<const DOMElement*
>(parent);
121 const std::string&
id) {
122 XMLCh* idChars = XMLString::transcode(
id.c_str());
123 DOMElement* elt = doc->getElementById(idChars);
124 XMLString::release(&idChars);
130 throw NullNode(
"Null node argument supplied to xmlBase::Dom::getNodeName");
132 const XMLCh* name = node->getNodeName();
133 if (!name)
return std::string(
"");
135 char* chrName = XMLString::transcode(name);
137 std::string strName = std::string(chrName);
138 XMLString::release(&chrName);
147 const std::string& tagName) {
149 throw NullNode(
"Null dom element argument to xmlBase::Dom::checkTagName");
151 if (tagName == std::string(
"*"))
return true;
152 XMLCh* xmlchTagName = XMLString::transcode(tagName.c_str());
153 bool ret = XMLString::equals(xmlchTagName, element->getTagName());
154 XMLString::release(&xmlchTagName);
161 const std::string& tagName,
162 std::vector<DOMElement*>& children,
165 throw NullNode(
"from xmlBase::Dom::getChildrenByTagName. Null parent arg");
167 if (clear) children.clear();
171 children.push_back(child);
179 const std::string& tagName,
180 std::vector<DOMElement*>& children,
183 throw NullNode(
"from xmlBase::Dom::getChildrenByTagName. Null parent arg");
185 if (clear) children.clear();
186 XMLCh* xmlchTagName = XMLString::transcode(tagName.c_str());;
188 parent->getElementsByTagName(xmlchTagName);
189 XMLString::release(&xmlchTagName);
190 unsigned int nItem = list->getLength();
191 for (
unsigned int iItem = 0; iItem < nItem; iItem++) {
192 children.push_back(
static_cast<DOMElement *
>(list->item(iItem)));
197 std::map<std::string, DOMNode*>& atts,
200 if (clear) atts.clear();
201 DOMNamedNodeMap* nodeMap = node->getAttributes();
202 unsigned int nAtts = nodeMap->getLength();
204 for (
unsigned iAtt = 0; iAtt < nAtts; iAtt++) {
205 DOMNode* attNode = nodeMap->item(iAtt);
212 if (node == 0)
return ret;
213 if (node->getNodeType() != DOMNode::ELEMENT_NODE )
return ret;
215 const DOMElement* elt =
static_cast<const DOMElement*
>(node);
216 XMLCh* xmlchAttName = XMLString::transcode(attName);
217 ret = (elt->getAttributeNode(xmlchAttName) != 0);
218 XMLString::release(&xmlchAttName);
224 throw NullNode(
"from xmlBase::Dom::getAttribute. Null argument");
227 XMLCh* xmlchAttName = XMLString::transcode(attName);
228 const XMLCh* attValue = elt->getAttribute(xmlchAttName);
229 XMLString::release(&xmlchAttName);
231 if (attValue == 0)
return std::string(
"");
233 char* chrAttValue = XMLString::transcode(attValue);
234 std::string strValue = std::string(chrAttValue);
235 XMLString::release(&chrAttValue);
241 std::string attName) {
248 throw NullNode(
"from xmlBase::Dom::getAttribute. Null argument");
251 if (elt->getNodeType() != DOMNode::ELEMENT_NODE) {
252 throw NullNode(
"from xmlBase::Dom::getAttribute. Non-element argument");
254 return getAttribute(
static_cast<const DOMElement*
>(elt), attName);
258 std::string attName) {
266 if (stringValue == std::string(
"") ) {
268 NullNode(
"from xmlBase::Dom::getDoubleAttribute. non-existent attribute");
280 std::vector<double>& values,
bool clear) {
282 std::vector<std::string> tokens;
283 if (clear) values.clear();
285 if (stringValue.size() == 0)
return nVals;
290 unsigned nToken = tokens.size();
291 for (
unsigned iToken = 0; iToken < nToken; iToken++) {
303 std::vector<float>& values,
bool clear) {
305 std::vector<std::string> tokens;
306 if (clear) values.clear();
308 if (stringValue.size() == 0)
return nVals;
313 unsigned nToken = tokens.size();
314 for (
unsigned iToken = 0; iToken < nToken; iToken++) {
329 if (stringValue == std::string(
"") ) {
331 NullNode(
"from xmlBase::Dom::getIntAttribute. non-existent attribute");
343 std::vector<int>& values,
bool clear) {
345 std::vector<std::string> tokens;
346 if (clear) values.clear();
348 if (stringValue.size() == 0)
return nVals;
353 unsigned nToken = tokens.size();
354 for (
unsigned iToken = 0; iToken < nToken; iToken++) {
367 short int nType = textNode->getNodeType();
369 if ( (nType != DOMNode::TEXT_NODE) &&
370 (nType != DOMNode::COMMENT_NODE) &&
371 (nType != DOMNode::CDATA_SECTION_NODE))
373 throw WrongNodeType(
"from xmlBase::Dom::getText, argument not text node");
375 const XMLCh*
t = textNode->getNodeValue();
376 if (
t == 0 )
return std::string(
"");
377 char* chrText = XMLString::transcode(
t);
378 std::string text = std::string(chrText);
379 XMLString::release(&chrText);
386 if (elt->getNodeType() != DOMNode::ELEMENT_NODE) {
387 throw WrongNodeType(
"from xmlBase::Dom::getTextContent, argument not element node");
389 return (
getText(elt->getFirstChild()));
395 throw NullNode(
"from xmlBase::Dom::addAttribute. null argument");
402 std::ostringstream
s;
406 std::string str =
s.str();
407 XMLCh* xmlchValue = XMLString::transcode(str.c_str());
408 XMLCh* xmlchName = XMLString::transcode(name.c_str());
411 elt->setAttribute(xmlchName, xmlchValue);
413 catch (DOMException ex) {
414 char* msg = XMLString::transcode(ex.msg);
415 std::cerr <<
"DOMException in xmlBase::Dom::addAttribute(double)" << std::endl;
416 std::cerr <<
"Msg: " << std::string(msg)
417 <<
"Code: " << ex.code << std::endl;
418 XMLString::release(&msg);
421 XMLString::release(&xmlchName);
422 XMLString::release(&xmlchValue);
429 throw NullNode(
"from xmlBase::Dom::addAttribute. Null argument");
437 std::ostringstream
s;
441 std::string str =
s.str();
443 XMLCh* xmlchValue = XMLString::transcode(str.c_str());
444 XMLCh* xmlchName = XMLString::transcode(name.c_str());
447 elt->setAttribute(xmlchName, xmlchValue);
449 catch (DOMException ex) {
450 char* msg = XMLString::transcode(ex.msg);
451 std::cerr <<
"DOMException in xmlBase::Dom::addAttribute(int)"
453 std::cerr <<
"Msg: " << std::string(msg)
454 <<
"Code: " << ex.code << std::endl;
455 XMLString::release(&msg);
459 XMLString::release(&xmlchName);
460 XMLString::release(&xmlchValue);
465 unsigned int value) {
467 throw NullNode(
"from xmlBase::Dom::addAttribute. Null argument");
474 std::ostringstream
s;
478 std::string str =
s.str();
480 XMLCh* xmlchValue = XMLString::transcode(str.c_str());
481 XMLCh* xmlchName = XMLString::transcode(name.c_str());
484 elt->setAttribute(xmlchName, xmlchValue);
486 catch (DOMException ex) {
487 char* msg = XMLString::transcode(ex.msg);
488 std::cerr <<
"DOMException in xmlBase::Dom::addAttribute(unsigned int)"
490 std::cerr <<
"Msg: " << std::string(msg)
491 <<
"Code: " << ex.code << std::endl;
492 XMLString::release(&msg);
495 XMLString::release(&xmlchName);
496 XMLString::release(&xmlchValue);
504 throw NullNode(
"from xmlBase::Dom::addAttribute. Null argument");
507 XMLCh* xmlchValue = XMLString::transcode(value);
508 XMLCh* xmlchName = XMLString::transcode(name.c_str());
511 elt->setAttribute(xmlchName, xmlchValue);
513 catch (DOMException ex) {
514 char* msg = XMLString::transcode(ex.msg);
515 std::cerr <<
"DOMException in xmlBase::Dom::addAttribute(char*)"
517 std::cerr <<
"Msg: " << std::string(msg) <<
"Code: "
518 << ex.code << std::endl;
520 XMLString::release(&msg);
524 XMLString::release(&xmlchName);
525 XMLString::release(&xmlchValue);
533 throw NullNode(
"from xmlBase::Dom::addAttribute. Null argument");
573 throw NullNode(
"from xmlBase::Dom::printElement. Null argument");
576 switch(node->getNodeType()) {
577 case DOMNode::ELEMENT_NODE:
582 out <<
'<' << tagName;
586 typedef std::map<std::string, DOMNode*> AttMap;
588 AttMap::const_iterator it;
591 for (it = atts.begin();
592 it != atts.end(); it++) {
593 std::string attName = (*it).first;
594 out <<
' ' << attName <<
'=';
599 DOMNode* child = node->getFirstChild();
604 child = child->getNextSibling();
609 out <<
"</" << endName <<
">";
617 case DOMNode::TEXT_NODE:
624 case DOMNode::CDATA_SECTION_NODE:
626 out <<
"<![CDATA[" <<
getText(node) <<
"]]>";
631 case DOMNode::COMMENT_NODE :
634 out <<
"<!-- " <<
getText(node) <<
"-->";
645 std::string prefix) {
649 throw NullNode(
"from xmlBase::Dom::prettyPrintElement. Null argument");
653 switch(node->getNodeType()) {
655 case DOMNode::ELEMENT_NODE:
659 out <<
'<' << tagName;
662 typedef std::map<std::string, DOMNode*> AttMap;
664 AttMap::const_iterator it;
668 for (it = atts.begin();
669 it != atts.end(); it++) {
670 std::string attName = (*it).first;
671 out <<
' ' << attName <<
'=';
676 DOMNode* child = node->getFirstChild();
678 out <<
'>' << std::endl;
682 child = child->getNextSibling();
687 out << prefix <<
"</" << endName <<
">" << std::endl;
691 out <<
" />" << std::endl;
695 case DOMNode::TEXT_NODE:
709 case DOMNode::CDATA_SECTION_NODE:
712 out <<
"<![CDATA[" <<
getText(node) <<
"]]>";
716 case DOMNode::COMMENT_NODE :
722 out <<
"<!-- " <<
getText(node) <<
"-->" << std::endl;
737 elt->removeChild(child);
741 char *Dom::transToChar(
const XMLCh*
const str) {
742 return transToChar(str, XMLString::stringLen(str) );
745 char *Dom::transToChar(
const XMLCh*
const str,
unsigned int len) {
749 if (str == 0)
return 0;
752 int status = initTrans();
753 if (!status)
return 0;
763 if (len + 1 > transBufSize) {
764 char * tBuf =
new char[len + 1];
766 transBufSize = len + 1;
772 ok = Dom::transcoder->transcode(str, transBuf, len);
773 return ( ok ? transBuf : 0);
777 XMLCh* Dom::transToXMLCh(
const char*
const src) {
780 if (src == 0)
return 0;
782 int status = initTrans();
783 if (!status)
return 0;
787 unsigned int len = strlen(src) + 1;
788 if (len > xmlchBufSize) {
789 XMLCh * tBuf =
new XMLCh[len];
798 ok = transcoder->transcode(src, xmlchBuf, len);
799 return (ok ? xmlchBuf : 0);
802 int Dom::initTrans() {
803 transcoder = XMLPlatformUtils::fgTransService->makeNewLCPTranscoder();
804 if (!transcoder)
return 0;
805 transBuf =
new char[transBufSize];
810 xmlchBuf =
new XMLCh[xmlchBufSize];
static double stringToDouble(const std::string &InStr)
static void stringTokenize(std::string input, const std::string &delimiters, std::vector< std::string > &tokens, bool clear=true)
static int stringToInt(const std::string &InStr)
Exception class used when converting from string to numeric type.
static std::string getTagName(const DOMElement *node)
static void getChildrenByTagName(const DOMElement *parent, const std::string &tagName, std::vector< DOMElement * > &children, bool clear=true)
static void addAttribute(DOMElement *elt, std::string name, double value)
Add attribute of type double to a DOM element, DOMString att name.
static int getIntAttribute(const DOMNode *elt, std::string attName)
static DOMElement * getSiblingElement(const DOMNode *child)
Return next element sibling, if any.
static unsigned getFloatsAttribute(const DOMNode *elt, std::string attName, std::vector< float > &values, bool clear=true)
static std::string getTextContent(const DOMElement *elt)
static void prettyPrintElement(DOMNode *elt, std::ostream &out, std::string prefix)
static void getAttributeNodeMap(const DOMNode *elt, std::map< std::string, DOMNode * > &atts, bool clear=true)
static void printElement(DOMNode *elt, std::ostream &out)
static bool hasAttribute(const DOMNode *elt, const char *attName)
static double getDoubleAttribute(const DOMNode *elt, std::string attName)
static DOMElement * getElementById(const DOMDocument *doc, const std::string &id)
static std::string getNodeName(const DOMNode *elt)
static std::string getAttribute(const DOMElement *elt, const char *attName)
static DOMElement * findFirstChildByName(const DOMElement *parent, const char *const name)
static void getDescendantsByTagName(const DOMElement *parent, const std::string &tagName, std::vector< DOMElement * > &children, bool clear=true)
static unsigned getDoublesAttribute(const DOMNode *elt, std::string attName, std::vector< double > &values, bool clear=true)
static DOMElement * getFirstChildElement(const DOMNode *parent)
Get first child which is an element node, if any.
static unsigned getIntsAttribute(const DOMNode *elt, std::string attName, std::vector< int > &values, bool clear=true)
static void prune(DOMElement *elt)
static std::string getText(const DOMNode *textNode)
static bool checkTagName(const DOMElement *element, const std::string &tagName)