(Is there any problem with setting the context node to a "/" in selectSingleNode?)
Not that I'm aware of. I've used the document root as the context node in both 'theEvaluator.evaluate() (or something like that) and in selectNodeList() in the example I gave you and have had no problems. -will -----Original Message----- From: Coker, Jonathan M [mailto:[EMAIL PROTECTED] Sent: Thursday, March 29, 2007 1:49 PM To: xalan-c-users@xml.apache.org Subject: RE: Xalan parser in a class Thanks Will. I will look through your code and get back with questions. I joined the list on 3/1 so I will look for archives to find your discussion with Dave. Part of what I am trying to do is clean up order dependencies in some initialization files. If I can collect a set of nodes from anywhere in a document then use each one of those as the context node for a data extractor function, I can get rid of some very inflexible code. (Is there any problem with setting the context node to a "/" in selectSingleNode?) Thanks again, Jonathan -----Original Message----- From: Will Sappington [mailto:[EMAIL PROTECTED] Sent: Thursday, March 29, 2007 11:56 AM To: xalan-c-users@xml.apache.org Subject: RE: Xalan parser in a class I cut out some code that illustrates what I did. I pasted it in-line below, prolly coulda' sent it as an attachment, OutHouse's word wrap really screws it up, but oh well. The issue I was having trouble with is that certain objects that need to be in member data (parserLiaison?) need the Xalan and Xerces platform initialization done before they are instantiated, but that can't happen if you are instantiating them as member data because the class constructor hasn't yet run. Dave suggested a way of doing this by creating a ProfileInit class that calls the ::initialize() methods in its constructor and then instantiating the init class before instantiating the Profile class. Prior to receiving his suggestion I had started work on doing the ::initialize() stuff in a static member that gets called to instantiate the profile. Either way works. Dave and I had some lengthy discussion about this in two threads that started around Feb. 12, one titled "problem evaluating XPath expressions" and the other a little later titled "Xalan initialization". Between the information in these threads and the sample code below, there should be enough to get you going. Dave's suggestion for handling the initialization appears in the "problem evaluating XPath expressions" thread on 2/14. HTH, -will class Profile { public: /*========================================= = public member data and functions ==========================================*/ /// get an instance of the profile static Profile* getInstance (const char* pFilespec = NULL) throw (NdmaEx&); /// delete an instance of the profile static void deleteInstance (Profile* pInstance) throw (NdmaEx&); /// open a profile with the specified filename void openProfile (const char* pFilespec) throw (NdmaEx&); /// retrieve an item from the profile const ProfileItem* getItem (const char* pAppName, const char* pSectionName, const char* pItemName) throw (NdmaEx&); /// close the profile void closeProfile () const; protected: private: XalanDocument* _pXmlDoc; ///< ptr to the Xalan DOM document XalanSourceTreeInit _sourceTreeInit; ///< source tree init class, ctor does init XalanSourceTreeDOMSupport _domSupport; ///< Xalan DOM support class XalanSourceTreeParserLiaison _parserLiaison; ///< helper class between parser & DOM }; Profile* Profile::getInstance (const char* pFilespec) throw (NdmaEx&) { Profile* pInstance = NULL; /* make sure we only initialize once */ if (instanceCount == 0) { /* intialize the Xerces system */ XMLPlatformUtils::Initialize(); /* initialize the Xalan XPath evaluator */ XPathEvaluator::initialize(); pInstance = new Profile(pFilespec); instanceCount++; } return (pInstance); } void Profile::deleteInstance (Profile* pInstance) throw (NdmaEx&) { pInstance->_close(); /* delete it anyway, if we're down to zero instances, shutdown the XML libraries */ delete pInstance; if (--instanceCount == 0) { XPathEvaluator::terminate(); XMLPlatformUtils::Terminate(); } return; } int Profile::openProfile (const char* pXmlFilespec) { // Hook the DOM support and the parser liaison together... _domSupport.setParserLiaison(&_parserLiaison); // convert the filename to a UTF-16 string for use by Xalan const XalanDOMString theFileName(pXmlFilespec); // Create an input source that represents a local file... step++; const LocalFileInputSource theInputSource(theFileName.c_str()); // Parse the document... step++; XalanDocument* const theDocument = _parserLiaison.parseXMLStream(theInputSource); if (theDocument == NULL) { /* parsing failed, set an error */ rc = E_ANY_ERROR; } else { /* set these member vars so the XPath stuff can use them */ _pXmlDoc = theDocument; } return (rc); } ProfileItem* Profile::getItem (const char* pAppName, const char* pSectionName, const char* pItemName) { XalanDocumentPrefixResolver thePrefixResolver(_pXmlDoc); XPathEvaluator theEvaluator; /* find the context node (the starting point... */ XalanNode* const pContextNode = theEvaluator.selectSingleNode(_domSupport, _pXmlDoc, XalanDOMString(pDfltContext).c_str(), thePrefixResolver); if (pContextNode == 0) { rc = E_ANY_ERROR; } else { /* found the context node, evaluate the expression */ NodeRefList nodeList; theEvaluator.selectNodeList(nodeList, _domSupport, pContextNode, XalanDOMString(xpathExpr).c_str(), _pXmlDoc->getDocumentElement()); const NodeRefList::size_type listLen = nodeList.getLength(); if (listLen == 0) { /* a zero length result means we didn't find it */ rc = E_ITEM_NOTFOUND; } else { /* got a set of item nodes, do something with them */ } } /* end (found the context node) */ return (rc); } -----Original Message----- From: Coker, Jonathan M [mailto:[EMAIL PROTECTED] Sent: Thursday, March 29, 2007 12:23 PM To: xalan-c-users@xml.apache.org Subject: RE: Xalan parser in a class I have started working on this but my first attempt fails during the creation of the prefixResolver. It looks like the NamespaceNodeTreeWalker instantiation is failing in the XalanDocumentPrefixResolver constructor. I am going to make sure I do not have any 'bookkeeping' errors and then I may post some code segments. Thanks again for all of the assistance. Jonathan -----Original Message----- From: Will Sappington [mailto:[EMAIL PROTECTED] Sent: Thursday, March 29, 2007 11:13 AM To: xalan-c-users@xml.apache.org Subject: RE: Xalan parser in a class I did exactly this (with help from Dave, Thanks Dave!) for an XML configuration file reader I just wrote. I put the XalanDocument*, XalanSourceTreeInit, XalanSourceTreeDOMSupport, and XalanSourceTreeParserLiaison in class member data. Works fine. Crazy busy for the next couple of hours but I'll post up some code snippets first chance I get. -will -----Original Message----- From: David Bertoni [mailto:[EMAIL PROTECTED] Sent: Wednesday, March 28, 2007 5:09 PM To: xalan-c-users@xml.apache.org Subject: Re: Xalan parser in a class Coker, Jonathan M wrote: > Hello, > Most of the examples I have seen have all of the Xalan code in a > single routine. I would like to wrap this in a class and break some of > the functionality into different member functions. For example, I would > like to create a function that would take node as an argument then use > it for the context node to evaluate a path. In order to do this it > seems like some of the things that are created (XercescDOMSupport, > XercesParserLiason, etc.) are good candidates for data members on the > class. Does this seem reasonable or am I going to have a lot of trouble > trying to do this? It's a reasonable thing, and essential if you're concerned with object lifetimes. For example, any documents you create with a XercesParserLiaison instance are destroyed when that instance goes out of scope. As a side note, I would encourage you to use Xalan-C's default source tree implementation, rather than the Xerces-C DOM, unless your application has a specific need for the Xerces-C DOM. Dave