- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我是 Xalan 和 Xerces 的新手,我尝试通过 XPath 选择一个特定节点。应该可以通过引用返回 xml 数据,但也需要更改 - 这就是为什么我将其保存为 DOMDocument 以便能够通过 xerces 访问数据以操作它们的原因。我有两种方法,一种是读取 xml 文件并进行模式验证,另一种是获取特定节点。我正在使用 Visual Studio 2012,当然还有 Xalan 和 Xerces 库。我试图创建一个 SSCCE 来向您展示我的问题:
头文件:
#pragma once
#include <string.h>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xalanc/Include/PlatformDefinitions.hpp>
#include <xalanc/XalanTransformer/XalanTransformer.hpp>
XALAN_CPP_NAMESPACE_USE
XERCES_CPP_NAMESPACE_USE
namespace CodeTest{
class Test
{
public:
Test(std::string schemaFilePath, std::string xmlFilePath){
mSchemaFilePath = schemaFilePath;
mXMLFilePath = xmlFilePath;
XMLPlatformUtils::Initialize();
XalanTransformer::initialize();
readXMLFile();
}
~Test(){
XalanTransformer::terminate();
XMLPlatformUtils::Terminate();
}
const XalanNode* getNode(XalanDOMString& path)const;
private:
Test();
Test(const Test&);
void readXMLFile();
std::string mSchemaFilePath;
std::string mXMLFilePath;
DOMDocument* mXMLDocument;
DOMElement* mRootElement;
XalanDocument* mXalanDocument;
XalanDocument* convertXercesDomDocumentToXalanDocument();
};
}
源文件:
#include "Test.h"
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xalanc/XPath/XPath.hpp>
#include <xalanc/XPath/XPathEvaluator.hpp>
#include <xalanc/XercesParserLiaison/XercesParserLiaison.hpp>
#include <xalanc/XercesParserLiaison/XercesDOMSupport.hpp>
#include <xalanc/XalanTransformer/XercesDOMWrapperParsedSource.hpp>
namespace CodeTest{
void Test::readXMLFile(){
XercesDOMParser xmlParser;
if (xmlParser.loadGrammar(mSchemaFilePath.c_str(), Grammar::SchemaGrammarType) == NULL){
fprintf(stderr, "couldn't load schema\n");
return;
}
xmlParser.setValidationScheme(XercesDOMParser::Val_Auto);
xmlParser.setDoNamespaces(true);
xmlParser.setDoSchema(true);
xmlParser.setValidationConstraintFatal(true);
xmlParser.parse(mXMLFilePath.c_str());
mXMLDocument = xmlParser.adoptDocument();
mXMLDocument->normalize();
mRootElement = mXMLDocument->getDocumentElement();
}
const XalanNode* Test::getNode(XalanDOMString& path)const{
XPathEvaluator theEvaluator;
XercesParserLiaison theParserLiaison;
XercesDOMSupport theDOMSupport(theParserLiaison);
XSLTInputSource xmlInput = mXMLFilePath.c_str();
XercesDOMWrapperParsedSource parsedSource(mXMLDocument, theParserLiaison, theDOMSupport, XalanDOMString(xmlInput.getSystemId()));
XalanDocument* xalanDocument = parsedSource.getDocument();
const XalanNode* node = theEvaluator.selectSingleNode(theDOMSupport, xalanDocument, path.c_str());
return node;
}
}
和我的主要功能:
#include "Test.h"
#include <string.h>
int main(){
std::string schemaFile = "d:/testDate.xsd";
std::string xmlFile = "d:/test.xml";
CodeTest::Test xmlParser(schemaFile, xmlFile);
XalanDOMString path("personnel/person[1]");
const XalanNode* node = xmlParser.getNode(path);
return 0;
}
问题是我需要通过引用返回节点及其所有属性。但问题是点头只是一个局部指针,如果他超出范围则无效。我已经尝试将其保存为成员变量,但指针的所有权属于 XercesDOMWrapperParsedSource,我无法将其创建为全局变量,因为我收到默认构造函数是私有(private)的错误消息。
所以我希望你们中的任何人都可以给我一些建议。
最佳答案
您不能只保留 XalanNode * 而忘记所有其他内容。如果您想在您的应用程序周围传递 XmlNode,您必须将它封装到您自己的类中,该类将在内部包含 XalanNode * 需要的所有内容。
为了证明这一点,我将附上我在我的项目中使用的一些辅助文件。这些文件将“按原样”粘贴,即你可能会在编译时遇到一些困难,因为它们是一个更大项目的一部分,并且有一些我将忽略的依赖项(比如 boost logging,boost::filesystem::path ; 你可以很容易地摆脱这些依赖)。然而,如果有人需要它,那么我相信他们会很容易地为您的项目调整它并理解这个想法。
提供的类旨在将 xml 文档加载到内存中,并允许使用 XPath 表达式读取它。
这是我的类的用法示例。
#include "tools/xalan/XalanRegistration.h"
#include "tools/xalan/XmlDoc.h"
#include "tools/xalan/XmlNode.h"
tools::xalan::XmlNode do_stuff_and_get_node() {
XmlDoc myDoc("file_to_load.xml");
return myDoc.getNode("/path/to/my/node");
}
int main(){
//this always goes to the main application scope
tools::xalan::XalanRegistration xalan;
//the rest may appear anywhere in your application
const tools::xalan::XmlNode my_node = do_stuff_and_get_node();
if (my_node.getBool("xpath/relative/to/my_node[@boolean_attr]")) {
std::out << my_node.getString("xpath/relative/to/my_node/text()");
}
const tools::xalan::XmlNode other_node = my_node("other/node");
//node holds internally the whole document so you can use also
//absolute xpath
auto more_nodes = other_node.getNodes("/i/want/more");
for (const tools::xalan::XmlNode &node: more_nodes) {
...
}
}
这里是包含的类(抱歉,如果这不是在本网站上附加更大内容的最佳方式)
主要实现在 XalanXmlDoc 中,它包含所有上下文但不可复制。 XmlDoc 和 XmlNode 可以方便地包装 XalanXmlDoc,以便可以轻松地在应用程序中传递文档或节点。
工具/xalan/XercesRegistration.h
#ifndef TOOLS_XERCES_XERCESREGISTRATION_H_
#define TOOLS_XERCES_XERCESREGISTRATION_H_
#include "NS-OPEN"
class XercesRegistration {
public:
/**
* This constructor calls:
* XMLPlatformUtils::Initialize();
*/
XercesRegistration();
/**
* This destructor calls:
* XMLPlatformUtils::Terminate();
*/
~XercesRegistration();
};
#include "NS-CLOSE"
#endif
工具/xalan/XercesRegistration.cpp
#include "XercesRegistration.h"
#include <xercesc/util/PlatformUtils.hpp>
#include "NS-OPEN"
XercesRegistration::XercesRegistration() {
using xercesc::XMLPlatformUtils;
//may throw xercesc::XMLException
XMLPlatformUtils::Initialize();
}
XercesRegistration::~XercesRegistration() {
using xercesc::XMLPlatformUtils;
XMLPlatformUtils::Terminate();
}
#include "NS-CLOSE"
工具/xalan/XalanRegistration.h
#ifndef TOOLS_XALAN_XALANREGISTRATION_H_
#define TOOLS_XALAN_XALANREGISTRATION_H_
#include "tools/xerces/XercesRegistration.h"
#include <xalanc/XalanSourceTree/XalanSourceTreeInit.hpp>
#include "NS-OPEN"
/**
* \brief XalanRegistration
*
* \author David Laštovička
*/
class XalanRegistration {
private:
typedef xerces::XercesRegistration XercesRegistration;
typedef xalanc::XalanSourceTreeInit XalanSourceTreeInit;
//may throw xercesc::XMLException
XercesRegistration xercesRegistration;
/**
* As seen in xalan-c-1.11/c/samples/SimpleXPathAPI/SimpleXPathAPI.cpp
*/
XalanSourceTreeInit theSourceTreeInit;
public:
/**
* \brief This constructor instantiates the object.
*/
XalanRegistration();
~XalanRegistration();
};
#include "NS-CLOSE"
#endif
工具/xalan/XalanRegistration.cpp
#include "XalanRegistration.h"
#include <xalanc/XPath/XPathEvaluator.hpp>
#include "NS-OPEN"
XalanRegistration::XalanRegistration() {
using xalanc::XPathEvaluator;
XPathEvaluator::initialize();
}
XalanRegistration::~XalanRegistration() {
using xalanc::XPathEvaluator;
XPathEvaluator::terminate();
}
#include "NS-CLOSE"
工具/xalan/XmlDoc.h
#ifndef TOOLS_XALAN_XMLDOC_H_
#define TOOLS_XALAN_XMLDOC_H_
#include <memory>
#include <set>
#include "XalanXmlDoc.h"
#include "XmlNode.fwd.h"
#include "tools/exception/EntityNotFound.h"
#include "tools/exception/NotUnique.h"
#include "NS-OPEN"
/**
* \brief XmlDoc is a simple reader for XML documents.
*
* It is meant to be used to:
* - read only
* - small documents fitting the memory
* - fetching data from the document with XPath
*
* XmlDoc allows to obtain and pass around a XmlNode representing only
* a part of the document.
*
* XmlDoc/XmlNode can be simply copied or moved around. All their copies
* internally share one instance of XalanXmlDoc that is released when the last
* XmlDoc/XmlNode is deleted.
*
* \author David Laštovička
*/
class XmlDoc {
private:
typedef std::string string;
typedef boost::filesystem::path path;
template<class T> using Container = std::vector<T>;
typedef tools::exception::EntityNotFound EntityNotFound;
typedef tools::exception::NotUnique NotUnique;
const std::shared_ptr<XalanXmlDoc> xalanXmlDoc;
public:
/**
* \brief This constructor instantiates the object.
*/
XmlDoc(const path &source);
XmlDoc(const std::shared_ptr<XalanXmlDoc> &xalanXmlDoc);
XmlDoc(const XmlDoc &) = default;
XmlDoc(XmlDoc &&) = default;
XmlNode getRoot() const;
string getString(const string &xpath) const
THROW(EntityNotFound);
Container<string> getStrings(const string &xpath) const;
std::set<string> getDistinctStrings(const string &xpath) const;
XmlNode getNode(const string &xpath) const
THROW(EntityNotFound);
Container<XmlNode> getNodes(const string &xpath) const;
};
#include "NS-CLOSE"
#endif /* TOOLS_XALAN_XMLDOC_H_ */
工具/xalan/XmlDoc.cpp
#include "XmlDoc.h"
#include "XmlNode.h"
#include "tools/llog/common.h"
#include "NS-OPEN"
XmlDoc::XmlDoc(const path &source)
: xalanXmlDoc(new XalanXmlDoc(source))
{
}
XmlDoc::XmlDoc(const std::shared_ptr<XalanXmlDoc> &xalanXmlDoc)
: xalanXmlDoc(xalanXmlDoc)
{
}
auto XmlDoc::getRoot() const
-> XmlNode
{
return getNode("/");
}
auto XmlDoc::getString(const string &xpath) const
THROW(EntityNotFound)
-> string
{
//may throw EntityNotFound, NotUnique
return xalanXmlDoc->getString(xpath);
}
auto XmlDoc::getStrings(const string &xpath) const
-> Container<string>
{
return xalanXmlDoc->getStrings(xpath);
}
auto XmlDoc::getDistinctStrings(const string &xpath) const
-> std::set<string>
{
using std::set;
//ToDo use distinct-values once XPath 2 available in Xalan
//auto depTypeCodeNodes = xmlDoc.getNodes("distinct-values(/module/dependencies/dependency/@type)");
auto values = getStrings(xpath);
set<string> res;
for (auto value: values)
res.insert(value);
return res;
}
auto XmlDoc::getNode(const string &xpath) const
THROW(EntityNotFound)
-> XmlNode
{
//may throw EntityNotFound, NotUnique
return XmlNode(xalanXmlDoc,xalanXmlDoc->getNode(xpath));
}
auto XmlDoc::getNodes(const string &xpath) const
-> Container<XmlNode>
{
using std::transform;
auto xalanNodes = xalanXmlDoc->getNodes(xpath);
Container<XmlNode> res;
transform(
xalanNodes.begin(), xalanNodes.end(),
back_inserter(res),
[this](const XalanXmlDoc::NodeHandle &xalanNode)->XmlNode
{
assert(xalanNode);
return XmlNode(this->xalanXmlDoc,xalanNode);
}
);
return res;
}
#include "NS-CLOSE"
工具/xalan/XmlNode.h
#ifndef TOOLS_XALAN_XMLNODE_H_
#define TOOLS_XALAN_XMLNODE_H_
#include "XalanXmlDoc.h"
#include "XmlDoc.fwd.h"
#include "tools/exception/EntityNotFound.h"
#include "tools/exception/NotUnique.h"
#include "NS-OPEN"
/**
* \brief XmlDoc
*
* \author David Laštovička
*/
class XmlNode {
private:
typedef std::string string;
template<class T> using Container = std::vector<T>;
typedef tools::exception::EntityNotFound EntityNotFound;
typedef tools::exception::NotUnique NotUnique;
/**
* In order to support move assignment and move operator this member
* is not const
*/
std::shared_ptr<XalanXmlDoc> xalanXmlDoc;
/**
* In order to support (the default) move assignment and move operator
* implementation this member is not const.
*/
XalanXmlDoc::NodeHandle node;
public:
/**
* Default constructor creates an empty node corresponding to this xml:
* </>
*/
XmlNode();
XmlNode(
const std::shared_ptr<XalanXmlDoc> &xalanXmlDoc,
const XalanXmlDoc::NodeHandle &node
);
XmlNode(const XmlNode &) = default;
XmlNode(XmlNode &&) = default;
XmlDoc getDoc() const;
string getString(const string &xpath) const
THROW(EntityNotFound);
string getString(const string &xpath, const string &defaultValue) const;
Container<string> getStrings(const string &xpath) const;
XmlNode getNode(const string &xpath) const
THROW(EntityNotFound);
Container<XmlNode> getNodes(const string &xpath) const;
bool getBool(const string &xpath) const
THROW(EntityNotFound);
/**
* \brief like getBool(xpath) but instead of throwing returns \arg defaultValue
*
*
*/
bool getBool(const string &xpath, bool defaultValue) const;
string getNodeName() const;
XmlNode &operator=(const XmlNode &) = default;
XmlNode &operator=(XmlNode &&) = default;
};
#include "NS-CLOSE"
#endif /* TOOLS_XALAN_XMLNODE_H_ */
工具/xalan/XmlNode.cpp
#include "XmlNode.h"
#include "XmlDoc.h"
#include "tools/llog/common.h"
#include "NS-OPEN"
XmlNode::XmlNode()
: xalanXmlDoc(new XalanXmlDoc(std::string("<empty/>"))),
node(xalanXmlDoc->getNode("/"))
{
assert(this->node);
}
XmlNode::XmlNode(
const std::shared_ptr<XalanXmlDoc> &xalanXmlDoc,
const XalanXmlDoc::NodeHandle &node
)
: xalanXmlDoc(xalanXmlDoc),
node(node)
{
assert(this->node);
}
XmlDoc XmlNode::getDoc() const
{
return XmlDoc(xalanXmlDoc);
}
auto XmlNode::getString(const string &xpath) const
THROW(EntityNotFound)
-> string
{
assert(node);
//may throw EntityNotFound
return xalanXmlDoc->getString(node,xpath);
}
auto XmlNode::getString(const string &xpath, const string &defaultValue) const
-> string
{
//may throw EntityNotFound
return xalanXmlDoc->getString(node,xpath,defaultValue);
}
auto XmlNode::getStrings(const string &xpath) const
-> Container<string>
{
return xalanXmlDoc->getStrings(node,xpath);
}
auto XmlNode::getNode(const string &xpath) const
THROW(EntityNotFound)
-> XmlNode
{
BOOST_LOG_FUNCTION();
//may throw EntityNotFound, NotUnique
return XmlNode(xalanXmlDoc,xalanXmlDoc->getNode(node,xpath));
}
auto XmlNode::getNodes(const string &xpath) const
-> Container<XmlNode>
{
using std::transform;
auto xalanNodes = xalanXmlDoc->getNodes(node,xpath);
Container<XmlNode> res;
transform(
xalanNodes.begin(), xalanNodes.end(),
back_inserter(res),
[this](const XalanXmlDoc::NodeHandle &xalanNode)->XmlNode
{
return XmlNode(this->xalanXmlDoc,xalanNode);
}
);
return res;
}
auto XmlNode::getBool(const string &xpath) const
THROW(EntityNotFound)
-> bool
{
//may throw EntityNotFound
return xalanXmlDoc->getBool(node,xpath);
}
auto XmlNode::getBool(const string &xpath, bool defaultValue) const
-> bool
{
return xalanXmlDoc->getBool(node,xpath,defaultValue);
}
auto XmlNode::getNodeName() const
-> string
{
return xalanXmlDoc->getNodeName(node);
}
#include "NS-CLOSE"
XmlDoc.fwd.h
#ifndef TOOLS_XALAN_XMLDOC_FWD_H_
#define TOOLS_XALAN_XMLDOC_FWD_H_
#include "NS-OPEN"
class XmlDoc;
#include "NS-CLOSE"
#endif /* TOOLS_XALAN_XMLDOC_FWD_H_ */
XmlNode.fwd.h
#ifndef TOOLS_XALAN_XMLNODE_FWD_H_
#define TOOLS_XALAN_XMLNODE_FWD_H_
#include "NS-OPEN"
class XmlNode;
#include "NS-CLOSE"
#endif /* TOOLS_XALAN_XMLNODE_FWD_H_ */
XalanXmlDoc.h
#ifndef TOOLS_XALAN_XALANXMLDOC_H_
#define TOOLS_XALAN_XALANXMLDOC_H_
#include <string>
#include <boost/filesystem.hpp>
#include <mutex>
#include <vector>
#include <sstream>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xalanc/XalanDOM/XalanDocument.hpp>
#include <xalanc/XalanSourceTree/XalanSourceTreeDOMSupport.hpp>
#include <xalanc/XalanSourceTree/XalanSourceTreeParserLiaison.hpp>
#include <xalanc/XPath/XPathEvaluator.hpp>
#include <xalanc/XSLT/XSLTInputSource.hpp>
#include "tools/exception/EntityNotFound.h"
#include "tools/exception/NotUnique.h"
#include "NS-OPEN"
/**
* \brief XalanXmlDoc
*
* This is expected to be used through XmlDoc and XmlNode rather than directly.
*
* \see xalan/build/linux-64/xalan-c-1.11/c/samples/XPathWrapper/XPathWrapper.cpp
*
* \author David Laštovička
*/
class XalanXmlDoc {
protected:
typedef std::string string;
typedef boost::filesystem::path path;
template<class T> using Container = std::vector<T>;
typedef xercesc::XercesDOMParser XercesDOMParser;
typedef xercesc::InputSource InputSource;
typedef xalanc::XalanDocument XalanDocument;
typedef xalanc::XalanSourceTreeDOMSupport XalanSourceTreeDOMSupport;
typedef xalanc::XercesParserLiaison XercesParserLiaison;
typedef xalanc::XalanSourceTreeParserLiaison XalanSourceTreeParserLiaison;
typedef xalanc::XalanElement XalanElement;
typedef xalanc::XalanNode XalanNode;
typedef std::mutex mutex;
typedef std::unique_lock<mutex> unique_lock;
typedef tools::exception::EntityNotFound EntityNotFound;
typedef tools::exception::NotUnique NotUnique;
public:
typedef const XalanNode* NodeHandle;
private:
/**
* ToDo review Xalan/Xerces behaviour when called concurrently. Maybe the
* mutex here is not necessary.
*/
mutex accessMutex;
mutable XalanSourceTreeDOMSupport domSupport;
XalanSourceTreeParserLiaison parserLiaison;
XalanDocument *xalanDoc;
public:
/**
* \brief This constructor instantiates the object.
*/
XalanXmlDoc(const path &sourceFile);
XalanXmlDoc(const string &xmlString);
XalanXmlDoc(const XalanXmlDoc &) = delete;
XalanXmlDoc(XalanXmlDoc &&) = delete;
~XalanXmlDoc();
NodeHandle get_root() const;
string getString(const string &xpath) const
THROW(EntityNotFound);
Container<string> getStrings(const string &xpath) const;
NodeHandle getNode(const string &xpath) const
THROW(EntityNotFound);
Container<NodeHandle> getNodes(const string &xpath) const;
string getString(const NodeHandle &xalanNode, const string &xpath) const
THROW(EntityNotFound);
string getString(const NodeHandle &xalanNode, const string &xpath, const string &defaultValue) const;
Container<string> getStrings(const NodeHandle &xalanNode, const string &xpath) const;
NodeHandle getNode(const NodeHandle &xalanNode, const string &xpath) const
THROW(EntityNotFound);
Container<NodeHandle> getNodes(
const NodeHandle &xalanNode, const string &xpath
) const;
/**
* When more elements do match xpath so the first one is returned.
* \throw EntityNotFound
*/
bool getBool(const NodeHandle &xalanNode, const string &xpath) const
THROW(EntityNotFound);
/**
* \brief like getBool(xalanNode, xpath) but instead of throwing EntityNotFound returns \arg defaultValue
*
*/
bool getBool(const NodeHandle &xalanNode, const string &xpath, bool defaultValue) const;
string getNodeName(const NodeHandle &xalanNode) const;
};
#include "NS-CLOSE"
#endif /* TOOLS_XALAN_XALANXMLDOC_H_ */
XalanXmlDoc.cpp
#include "XalanXmlDoc.h"
#include <xercesc/sax/HandlerBase.hpp>
#include <xalanc/XPath/XPathEvaluator.hpp>
#include <xalanc/XPath/NodeRefList.hpp>
#include <xalanc/XalanDOM/XalanElement.hpp>
#include <xalanc/XalanDOM/XalanNamedNodeMap.hpp>
#include "tools/llog/common.h"
#include <sstream>
#include <vector>
#include "tools/text/ostream_iterator.h"
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include "tools/exception/Other.h"
#include "tools/exception/util/backtraceFactory.obj.h"
#include <xalanc/DOMSupport/XalanDocumentPrefixResolver.hpp>
#include "NS-OPEN"
static std::string toString(const xalanc::XalanDOMString &val)
{
return std::string(val.begin(), val.end());
}
static void outputAttrs(std::ostream &oss, xalanc::XalanNode const * const node)
{
using std::ostringstream;
using xalanc::XalanNode;
using xalanc::XalanElement;
using xalanc::XalanSize_t;
if (node->getNodeType()==XalanNode::ELEMENT_NODE) {
XalanElement const * const element = static_cast<XalanElement const * const>(node);
oss << "[";
for (XalanSize_t i = 0; i<element->getAttributes()->getLength(); i++) {
if (i>0) oss << ' ';
oss << '@' << toString(element->getAttributes()->item(i)->getNodeName())
<< "='"
<< toString(element->getAttributes()->item(i)->getNodeValue())
<< "'";
}
oss << "]";
}
}
static void outputFullPathWithAttrs(
std::ostream &oss,
xalanc::XalanNode const * const node,
bool outputAttrsRequested
)
{
using std::ostringstream;
using std::string;
using std::vector;
using tools::text::ostream_iterator;
using std::copy;
using xalanc::XalanNode;
vector<string> nodeNames;
{
for(XalanNode const *it = node; it!=nullptr; it=it->getParentNode())
{
ostringstream oss;
oss << toString(it->getNodeName());
if (outputAttrsRequested)
outputAttrs(oss, it);
nodeNames.push_back(oss.str());
}
}
copy(
nodeNames.rbegin(), nodeNames.rend(),
ostream_iterator<string>(oss,nullptr,nullptr,"/")
);
}
/*
static std::string createFullPath(xalanc::XalanNode const * const node)
{
using std::ostringstream;
ostringstream oss;
outputFullPathWithAttrs(oss,node,false);
return oss.str();
}
*/
static std::string createFullPathWithAttrs(xalanc::XalanNode const * const node)
{
using std::ostringstream;
ostringstream oss;
outputFullPathWithAttrs(oss,node,true);
return oss.str();
}
XalanXmlDoc::XalanXmlDoc(const path &source)
: //domSupport(parserLiaison),
parserLiaison(domSupport)
{
using xercesc::LocalFileInputSource;
using xalanc::XalanDOMString;
domSupport.setParserLiaison(&parserLiaison);
const XalanDOMString theFileName(source.native().c_str());
LocalFileInputSource theInputSource(theFileName.c_str());
xalanDoc = parserLiaison.parseXMLStream(theInputSource);
}
XalanXmlDoc::XalanXmlDoc(const string &xmlString)
: //domSupport(parserLiaison),
parserLiaison(domSupport)
{
using xercesc::MemBufInputSource;
using xalanc::XalanDOMString;
domSupport.setParserLiaison(&parserLiaison);
MemBufInputSource theInputSource(
(const XMLByte *)xmlString.c_str(),
xmlString.size(),
"XalanXmlDoc"
);
xalanDoc = parserLiaison.parseXMLStream(theInputSource);
}
XalanXmlDoc::~XalanXmlDoc()
{
}
auto XalanXmlDoc::get_root() const
-> NodeHandle
{
return xalanDoc;
}
auto XalanXmlDoc::getString(const string &xpath) const
THROW(EntityNotFound)
-> string
{
//may throw EntityNotFound, NotUnique
return getString(get_root(),xpath);
}
auto XalanXmlDoc::getStrings(const string &xpath) const
-> Container<string>
{
return getStrings(get_root(),xpath);
}
auto XalanXmlDoc::getNode(const string &xpath) const
THROW(EntityNotFound)
-> NodeHandle
{
//may throw EntityNotFound, NotUnique
return getNode(get_root(), xpath);
}
auto XalanXmlDoc::getNodes(const string &xpath) const
-> Container<NodeHandle>
{
return getNodes(get_root(), xpath);
}
auto XalanXmlDoc::getString(const NodeHandle &xalanNode, const string &xpath) const
THROW(EntityNotFound)
-> string
{
//may throw EntityNotFound, NotUnique
auto found = getNode(xalanNode, xpath);
return toString(found->getNodeValue());
}
auto XalanXmlDoc::getString(const NodeHandle &xalanNode, const string &xpath, const string &defaultValue) const
-> string
{
using exception::EntityNotFound;
string res;
try {
//may throw EntityNotFound
auto found = getNode(xalanNode, xpath);
res = toString(found->getNodeValue());
} catch (const EntityNotFound &e) {
res = defaultValue;
}
return res;
}
auto XalanXmlDoc::getStrings(const NodeHandle &xalanNode, const string &xpath) const
-> Container<string>
{
Container<string> res;
for (auto node: getNodes(xalanNode, xpath))
{
res.push_back(toString(node->getNodeValue()));
}
return res;
}
auto XalanXmlDoc::getNode(const NodeHandle &xalanNode, const string &xpath) const
THROW(EntityNotFound)
-> NodeHandle
{
BOOST_LOG_FUNCTION();
using xalanc::XalanNode;
using xalanc::XalanDOMString;
using xalanc::XPathEvaluator;
using std::ostringstream;
using xercesc::SAXParseException;
using xalanc::XalanDocumentPrefixResolver;
#ifndef NDEBUG
if (!xalanNode) {
BOOST_LOG_TRIVIAL(trace)
<< "Assertion failed evaluating " << xpath;
BOOST_LOG_TRIVIAL(trace)
<< tools::exception::util::backtraceFactory().createBacktraces();
}
assert(xalanNode);
{
std::ostringstream oss;
outputFullPathWithAttrs(oss,xalanNode,true);
BOOST_LOG_TRIVIAL(trace)
<< "XalanXmlDoc::getNode " << xpath << " on type "
<< xalanNode->getNodeType()
<< " in " << oss.str();
}
#endif
//ToDo try can be removed the SAXParseException probably not thrown here but in the constructor
try {
XalanDocumentPrefixResolver thePrefixResolver(xalanDoc);
const XalanDOMString expression(xpath.c_str());
BOOST_LOG_TRIVIAL(trace) << "expression prepared";
XPathEvaluator evaluator;
//better use mutex when accessing the global domSupport etc.
unique_lock(accessMutex);
const XalanNode* found = evaluator.selectSingleNode(
domSupport,
const_cast<XalanNode *>(xalanNode),
expression.c_str(),
thePrefixResolver
);
if (!found) {
ostringstream oss;
oss << "Not found " << xpath << " on the node " << createFullPathWithAttrs(xalanNode);
throw EntityNotFound(SRCINF, oss.str());
}
assert(found);
BOOST_LOG_TRIVIAL(trace) << "returning node";
return found;
} catch (const SAXParseException &e) {
using std::ostringstream;
using exception::Other;
ostringstream oss;
oss << "SAXParseException line: " << e.getLineNumber() << " column: "
<< e.getColumnNumber() << " message: " << e.getMessage();
throw Other(SRCINF,oss.str());
}
}
auto XalanXmlDoc::getNodes(const NodeHandle &xalanNode, const string &xpath) const
-> Container<NodeHandle>
{
using xalanc::XalanNode;
using xalanc::XalanDOMString;
using xalanc::XPathEvaluator;
using xalanc::NodeRefList;
using xercesc::SAXParseException;
using xalanc::XalanDocumentPrefixResolver;
BOOST_LOG_TRIVIAL(trace)
<< "XalanXmlDoc::getNodes " << xpath;
//ToDo try can be removed the SAXParseException probably not thrown here but in the constructor
try {
XalanDocumentPrefixResolver thePrefixResolver(xalanDoc);
const XalanDOMString expression(xpath.c_str());
XPathEvaluator evaluator;
NodeRefList foundNodes;
{
//better use mutex when accessing the global domSupport etc.
unique_lock(accessMutex);
evaluator.selectNodeList(
foundNodes,
domSupport,
const_cast<XalanNode *>(xalanNode),
expression.c_str(),
thePrefixResolver
);
}
std::vector<const XalanNode*> res;
for (NodeRefList::size_type i=0;i<foundNodes.getLength();i++) {
assert(foundNodes.item(i));
res.push_back(foundNodes.item(i));
}
return res;
} catch (const SAXParseException &e) {
using std::ostringstream;
using exception::Other;
ostringstream oss;
oss << "SAXParseException line: " << e.getLineNumber() << " column: "
<< e.getColumnNumber() << " message: " << e.getMessage();
throw Other(SRCINF,oss.str());
}
}
auto XalanXmlDoc::getBool(const NodeHandle &xalanNode, const string &xpath) const
THROW(EntityNotFound)
-> bool
{
bool res;
//may throw EntityNotFound, NotUnique
std::istringstream(getString(xalanNode,xpath)) >> std::boolalpha >> res;
return res;
}
auto XalanXmlDoc::getBool(const NodeHandle &xalanNode, const string &xpath, bool defaultValue) const
-> bool
{
using exception::EntityNotFound;
bool res;
try {
//may throw EntityNotFound, NotUnique
res = getBool(xalanNode,xpath);
} catch (const EntityNotFound &e) {
res = defaultValue;
}
return res;
}
auto XalanXmlDoc::getNodeName(const NodeHandle &xalanNode) const
-> string
{
assert(xalanNode);
return toString(xalanNode->getNodeName());
}
#include "NS-CLOSE"
关于c++ - Xalan C++ : returning a node with XPath (reference to local pointer),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20514842/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!