#include "common/StringUtils.hpp" #include "xml/XMLDocument.hpp" #include "xml/XMLInit.hpp" #include "xml/NamespaceResolver.hpp" #include #include #include #include #include #include #include #include #include #include #include // #include // Is this the right include when using a Xerces parse? Or does xalan use its // own in some way, or whould be use 'PrefixResolver' raw and create // a liason object per JR comments? #include #include #include using namespace xercesc; using namespace xalanc; using namespace std; XMLDocument::XMLDocument(DOMDocument *doc, NamespaceResolver *resolver) : _doc(doc) { XMLInit::init(); _root = _doc->getDocumentElement(); _xerces_doc_wrapper = new XercesDocumentWrapper(*XMLPlatformUtils::fgMemoryManager, _doc); this->resolver = resolver; // Xalan wrapper _xalan_doc = _xerces_doc_wrapper->getOwnerDocument(); _xalan_root = static_cast(_xerces_doc_wrapper->getDocumentElement()); } XMLDocument::~XMLDocument() { delete _xerces_doc_wrapper; _doc->release(); } const XalanNode* XMLDocument::getElement(const string &query) const throw (XPathExpressionException) { XPathEvaluator theEvaluator; try { return theEvaluator.selectSingleNode(XMLInit::theDOMSupport(), _xalan_root, XalanDOMString(query.c_str()).c_str(), *resolver); } catch (const XPathParserException& e) { CharVectorType msg; e.getMessage().transcode(msg); throw XPathExpressionException(msg.begin()); } return theEvaluator.selectSingleNode(XMLInit::theDOMSupport(), _xalan_root, XalanDOMString(query.c_str()).c_str(), *resolver); } int XMLDocument::getNodeCount(const string& query) const throw (XPathExpressionException) { XPathEvaluator theEvaluator; try { XObjectPtr theResult = theEvaluator.evaluate(XMLInit::theDOMSupport(), _xalan_root, XalanDOMString(query.c_str()).c_str(), *resolver); if (theResult->getType() != XObject::eTypeNumber) { throw XPathExpressionException( "Result of XPath expression was not a number."); } return (int)theResult->num(); } catch (const XPathParserException& e) { CharVectorType msg; e.getMessage().transcode(msg); throw XPathExpressionException(msg.begin()); } } const NodeRefList XMLDocument::getElements(const string &query) const throw (XPathExpressionException) { XPathEvaluator theEvaluator; NodeRefList theList; try { theEvaluator.selectNodeList(theList, XMLInit::theDOMSupport(), _xalan_root, XalanDOMString(query.c_str()).c_str(), *resolver); return theList; } catch (const XPathParserException& e) { CharVectorType msg; e.getMessage().transcode(msg); throw XPathExpressionException(msg.begin()); } } string XMLDocument::getNodeValue(const string &query) const throw (XPathExpressionException) { XPathEvaluator theEvaluator; try { XObjectPtr theResult = theEvaluator.evaluate(XMLInit::theDOMSupport(), _xalan_root, XalanDOMString(query.c_str()).c_str(), *resolver); CharVectorType res; theResult->str().transcode(res); return res.begin(); } catch(const XPathParserException& e) { CharVectorType msg; e.getMessage().transcode(msg); throw XPathExpressionException(msg.begin()); } } string XMLDocument::getNodeName(const string &query, bool throwIfUnmatched) const throw (XPathExpressionException) { const XalanNode *element = getElement(query); if (element == NULL) { if (throwIfUnmatched) throw XPathExpressionException( "Can not resolve node name because XPATH query '" + query + "' does not match any nodes."); else return ""; } CharVectorType res; element->getLocalName().transcode(res); return res.begin(); } vector XMLDocument::getChildNames(const string& query) const throw (XPathExpressionException) { vector names; NodeRefList nodes = getElements(query + "/*"); for (NodeRefList::size_type i = 0; i < nodes.getLength(); ++i) { XalanDOMString str = nodes.item(i)->getLocalName(); names.push_back(c_str(TranscodeToLocalCodePage(str))); } return names; } vector XMLDocument::getNodeValues(const string &query) const throw (XPathExpressionException) { vector values; NodeRefList nodes = getElements(query); for (NodeRefList::size_type i = 0; i < nodes.getLength(); ++i) { string q = query + "[" + StringUtils::makeString((int) i + 1) + "]/text()"; string s = getNodeValue(q); values.push_back(s); } return values; }