You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-users@xalan.apache.org by Will Sappington <ws...@ndma.us> on 2007/02/12 04:37:27 UTC
Problem evaluating XPath expressions
Hello all,
I'm writing a configuration utility that we call an "application
profile" or simply profile, that is essentially an ini file on steroids.
It's a hierarchical structure - application/section/item - that allows
multiple applications to use a single profile. I'm migrating it from
"key = value" format to XML and I'm using Xalan/Xerces for evaluating
XPath expressions to retrieve the configuration items.
>From a functional standpoint, the interface to the profile is:
- open the profile (load the XML file, parse it into a DOM
tree)
- execute a getItem() call for each of the one or more items to
be retrieved
- close the profile
After using the SimpleXPath... sample program to set up a working XPath
evaluation, I tried splitting things up along open/read/close functional
lines. That is, I tried reading the XML file and parsing it into a
Xalan DOM tree in the open() method, doing the XPath evaluation in the
getItem() method, and the terminate() functions in the close() method.
To do this I had to put certain objects common to the open() and
getItem() methods into Profile class member data, specifically the
XalanDocument* and the XalanSourceTreeDOMSupport.
The open() method runs successfully, parses the doc, and sets up the
XalanDocument pointer. However, when I try to evaluate an XPath
expression, the instantiation of the XalanDocumentPrefixResolver object
fails with a "generic" exception, that is:
XalanDocumentPrefixResolver thePrefixResolver(_pXmlDoc);
where _pXmlDoc is in the Profile class private member data
throws an exception caught by the (...) catch. The code for the methods
in question is below. Is there a way to do what I'm trying to do? Can
I, from inside what is essentially a wrapper class, open and parse a
document into a DOM tree in one method, and then use the results of that
method to execute one or more XPath evaluations against the DOM tree in
another method? I'd really hate to have to parse the document every
time a user makes a call to getItem(). Thanks in advance, any help
would be most appreciated.
Best,
-will (code follows, catches and some other irrelevant stuff left out
for brevity)
int Profile::_openXmlDoc (const char* pXmlFilespec)
{
try
{
XMLPlatformUtils::Initialize();
XPathEvaluator::initialize();
{
// Initialize the XalanSourceTree subsystem...
XalanSourceTreeInit theSourceTreeInit;
// We'll use these to parse the XML file.
// now declared in private member data
// XalanSourceTreeDOMSupport theDOMSupport;
XalanSourceTreeParserLiaison theLiaison(_DomSupport);
// Hook the two together...
_DomSupport.setParserLiaison(&theLiaison);
const XalanDOMString theFileName(pXmlFilespec);
// Create an input source that represents a local file...
const LocalFileInputSource
theInputSource(theFileName.c_str());
// Parse the document...
XalanDocument* const theDocument =
theLiaison.parseXMLStream(theInputSource);
if (theDocument == NULL)
{
::sprintf(_zErr, "Error (%s): document parsing failed
for file (%s)\n",
pThisFnc, theFileName.c_str());
rc = E_ANY_ERROR;
}
else
{
/* set these member vars so the XPath stuff can use them
*/
_pXmlDoc = theDocument;
}
}
}
return (rc);
} // end _open()
int Profile::_getStringItem (const char* pAppName, const char*
pSectionName, const char* pItemName,
char* pBufRet, size_t& bufLen)
{
::memset((void*)xpathExpr, 0, sizeof(xpathExpr));
::sprintf(xpathExpr, pXPathTplt, pAppName, pSectionName, pItemName);
try
{
// use the document pointer stored in member data
// ** this statement throws an exception caught by the (...)
catch
XalanDocumentPrefixResolver thePrefixResolver(_pXmlDoc);
XPathEvaluator theEvaluator;
// OK, let's find the context node... using member data for
DomSupport and pXmlDoc?
// but we never get to this point
XalanNode* const pContextNode =
theEvaluator.selectSingleNode(_DomSupport,
_pXmlDoc,
XalanDOMString(pDfltContext).c_str(),
thePrefixResolver);
if (pContextNode == 0)
{
::sprintf(_zErr, "Error (%s): No nodes matched the context
path (%s)\n",
pThisFnc, pDfltContext);
rc = E_ANY_ERROR;
}
else
{
// OK, let's evaluate the expression...
const XObjectPtr
theResult(theEvaluator.evaluate(_DomSupport,
pContextNode,
XalanDOMString(xpathExpr).c_str(),
thePrefixResolver));
if (theResult.null())
{
/* a null result means we didn't find it, set the
returned length
to zero and set an error */
bufLen = 0;
::sprintf(_zErr, "Warning (%s): item not found, no node
matched "
"the XPath expression:\n (%s)\n",
pThisFnc, xpathExpr);
rc = E_ITEM_NOTFOUND;
}
else
{
/* we found something, jump through a couple of hoops to
get it
into a C-string, copy it to the return buffer, and
set the
returned length */
/* the transcode method transcodes the result string
(UTF-16) to
chars and stores them in a vector of chars. the
chars from
the vector are then assigned to a std::string object
by
iterating through the vector. once assigned to the
string
they are in a form we can use them. */
XalanVector<char> charData;
std::string rtnStr;
theResult->str().transcode(charData);
rtnStr.assign(charData.begin(), charData.end());
/* clear the return buffer, copy the string in, and set
the returned length */
::memset((void*)pBufRet, 0, bufLen);
::strncpy(pBufRet, rtnStr.c_str(), bufLen - 1);
pBufRet[bufLen - 1] = 0;
bufLen = ::strlen(rtnStr.c_str());
}
}
}
return (rc);
} // end getItem()
RE: Problem evaluating XPath expressions
Posted by Will Sappington <ws...@ndma.us>.
Thanks Dave for the quick reply, I'll try what you suggest.
-will
-----Original Message-----
From: David Bertoni [mailto:dbertoni@apache.org]
Sent: Monday, February 12, 2007 1:50 AM
To: xalan-c-users@xml.apache.org
Subject: Re: Problem evaluating XPath expressions
Will Sappington wrote:
> Hello all,
>
>
>
> I'm writing a configuration utility that we call an "application
> profile" or simply profile, that is essentially an ini file on
> steroids. It's a hierarchical structure - application/section/item -
> that allows multiple applications to use a single profile. I'm
> migrating it from "key = value" format to XML and I'm using
Xalan/Xerces
> for evaluating XPath expressions to retrieve the configuration items.
>
...
>
> XalanDocumentPrefixResolver thePrefixResolver(_pXmlDoc);
>
>
>
> where _pXmlDoc is in the Profile class private member data
>
From looking at your code, I suspect the _pXmlDoc data member is
pointing
to an instance that's already been destroyed.
Here's what the comments for XMLParserLiason::parseXMLStream() say:
/**
* Parse the text pointed at by the reader as XML, and return a DOM
* Document interface. It is recommended that you pass in some sort of
* recognizable name, such as the filename or URI, with which the
reader
* can be recognized if the parse fails.
*
* The liaison owns the XalanDocument instance, and will delete it when
* when asked (see DestroyDocument()), or when the liaison is reset, or
* goes out of scope.
*/
So, the instance you created is destroyed when the
XalanSourceTreeParserLiaison instance is destroyed in
Profile::_openXmlDoc().
In general, Xalan-C implements very tightly controlled ownership of
objects. The easiest way for you to handle this is to make the
XalanSourceTreeParserLiason instance a member of your class.
Dave
Re: XPath result - null or zero length?
Posted by David Bertoni <db...@apache.org>.
Will Sappington wrote:
> I searched the archives for "xpath result" (unquoted) and didn't get any
> useful hits so:
>
> The SimpleXPathAPI example does this after establishing the context
> node:
>
> // OK, let's evaluate the expression...
> const XObjectPtr theResult(
> theEvaluator.evaluate(
> theDOMSupport,
> theContextNode,
> XalanDOMString(argv[3]).c_str(),
> thePrefixResolver));
>
> assert(theResult.null() == false);
>
> cout << "The string value of the result is:"
> << endl
> << theResult->str()
> << endl
> << endl;
>
> It would appear from this that the test for an unsuccessful XPath
> evaluation is theResult.null() returning true. However, if I evaluate
> an XPath expression containing an element or attribute that is not in
> the file, that test fails - .null() returns false - and after converting
> the result to a regular C char string, it is empty, zero length. If I
> give the SimpleXPathAPI sample program an expression that will not
> match, it prints "The string value of the result is ", indicating that
> it too got a zero length result instead of null.
XObjectPtr is a smart-pointer class, so the call to the null() member
function just determines whether or not it's pointing to an XObject
instance. In this case,
Any calls made using the -> operator are passed on to the underlying
XObject instance. The XObject class holds the actual result of the
evaluation. It's type depends on the type of the XPath expression you've
evaluated.
If you get a zero-length string, that just means that the result of the
expression has that value. That could be an empty string, or an empty
node-set.
>
> The API docs for XPathEvaluator::evaluate() just say that it returns the
> result of the search. To find out exactly what that is, I dug through
> the XPathEvaluator::evaluate() code as far as I could but I got lost in
> all the cases in XPath::executeMore(). Searched the archive but didn't
> find anything.
The result of an XPath 1.0 expression can have a type of string, number,
boolean or node-set. I'm assuming most of your expressions are location
paths, so those will be of type node-set. In that case, you can call
XObject::nodeset(), to get a reference to the underlying NodeRefListBase
instance. However, if the expression is not a node-set, then calling that
function will result in an exception. If you're worried about the type of
the resulting XObject instance, you can call XObject::getType()
>
> Q: which test should I use for an unsuccessful match, null or zero
> length, or could I get both and they mean different things?
You call nodeset() to get a reference to the underlying NodeRefListBase,
then call getLength() to see how many nodes there are.
Dave
XPath result - null or zero length?
Posted by Will Sappington <ws...@ndma.us>.
I searched the archives for "xpath result" (unquoted) and didn't get any
useful hits so:
The SimpleXPathAPI example does this after establishing the context
node:
// OK, let's evaluate the expression...
const XObjectPtr theResult(
theEvaluator.evaluate(
theDOMSupport,
theContextNode,
XalanDOMString(argv[3]).c_str(),
thePrefixResolver));
assert(theResult.null() == false);
cout << "The string value of the result is:"
<< endl
<< theResult->str()
<< endl
<< endl;
It would appear from this that the test for an unsuccessful XPath
evaluation is theResult.null() returning true. However, if I evaluate
an XPath expression containing an element or attribute that is not in
the file, that test fails - .null() returns false - and after converting
the result to a regular C char string, it is empty, zero length. If I
give the SimpleXPathAPI sample program an expression that will not
match, it prints "The string value of the result is ", indicating that
it too got a zero length result instead of null.
The API docs for XPathEvaluator::evaluate() just say that it returns the
result of the search. To find out exactly what that is, I dug through
the XPathEvaluator::evaluate() code as far as I could but I got lost in
all the cases in XPath::executeMore(). Searched the archive but didn't
find anything.
Q: which test should I use for an unsuccessful match, null or zero
length, or could I get both and they mean different things?
Thanks in advance,
-will
RE: Xalan initialization
Posted by Will Sappington <ws...@ndma.us>.
-----Original Message-----
From: David Bertoni [mailto:dbertoni@apache.org]
Sent: Thursday, February 15, 2007 5:48 PM
To: xalan-c-users@xml.apache.org
Subject: Re: Xalan initialization
Will Sappington wrote:
> While researching the XPath evaluator question I came across something
> that raised a question about Xalan initialization so I'll ask it while
I
> continue digging.
>
> I came across the following in the mail list archive, dated
2006-04-26,
> re: "Regarding XPath query":
>
> As I said previously, the best thing to do is to call
>> XalanTransformer::initialize() in main(), and remove any usage of the
>> "Init" classes.
>
> The sample app on which the code I'm writing is based - SimpleXPathAPI
-
> calls XMLPlatformUtils::Initialize() and XPathEvaluator::initialize()
> and also instantiates a XalanSourceTreeInit class.
>
> My code does exactly this and is working. The example code Dave sent
me
> in a previous post uses XalanTransformer::initialize() instead of
> XPathEvaluator::initialize().
What you're doing is fine, but not everything is initialized when you do
this.
>
> Q: should I replace XPathEvaluator::initialize() with
> XalanTransformer::initialize()? (probably yes)
This initializes more stuff, so it will use more memory, etc. The
advantage is you avoid mysterious crashes when you start using something
in
another subsystem, and you forgot to do further initialization.
>
> Q: do I still need the XalanSourceTreeInit class? (really don't know)
If you use XalanTransformer::initialize(), then you don't need
XPathEvaluator::initialize() or XalanSourceTreeInit. For more details,
take a look at what XalanTransformer::initialize() does, vs. what
XPathEvaluator::initialize() does, vs. what the class
XalanSourceTreeInit does.
Dave
==================
Thank you,
-will
Re: Xalan initialization
Posted by David Bertoni <db...@apache.org>.
Will Sappington wrote:
> While researching the XPath evaluator question I came across something
> that raised a question about Xalan initialization so I'll ask it while I
> continue digging.
>
> I came across the following in the mail list archive, dated 2006-04-26,
> re: "Regarding XPath query":
>
> As I said previously, the best thing to do is to call
>> XalanTransformer::initialize() in main(), and remove any usage of the
>> "Init" classes.
>
> The sample app on which the code I'm writing is based - SimpleXPathAPI -
> calls XMLPlatformUtils::Initialize() and XPathEvaluator::initialize()
> and also instantiates a XalanSourceTreeInit class.
>
> My code does exactly this and is working. The example code Dave sent me
> in a previous post uses XalanTransformer::initialize() instead of
> XPathEvaluator::initialize().
What you're doing is fine, but not everything is initialized when you do this.
>
> Q: should I replace XPathEvaluator::initialize() with
> XalanTransformer::initialize()? (probably yes)
This initializes more stuff, so it will use more memory, etc. The
advantage is you avoid mysterious crashes when you start using something in
another subsystem, and you forgot to do further initialization.
>
> Q: do I still need the XalanSourceTreeInit class? (really don't know)
If you use XalanTransformer::initialize(), then you don't need
XPathEvaluator::initialize() or XalanSourceTreeInit. For more details,
take a look at what XalanTransformer::initialize() does, vs. what
XPathEvaluator::initialize() does, vs. what the class XalanSourceTreeInit does.
Dave
Xalan initialization
Posted by Will Sappington <ws...@ndma.us>.
While researching the XPath evaluator question I came across something
that raised a question about Xalan initialization so I'll ask it while I
continue digging.
I came across the following in the mail list archive, dated 2006-04-26,
re: "Regarding XPath query":
As I said previously, the best thing to do is to call
> XalanTransformer::initialize() in main(), and remove any usage of the
> "Init" classes.
The sample app on which the code I'm writing is based - SimpleXPathAPI -
calls XMLPlatformUtils::Initialize() and XPathEvaluator::initialize()
and also instantiates a XalanSourceTreeInit class.
My code does exactly this and is working. The example code Dave sent me
in a previous post uses XalanTransformer::initialize() instead of
XPathEvaluator::initialize().
Q: should I replace XPathEvaluator::initialize() with
XalanTransformer::initialize()? (probably yes)
Q: do I still need the XalanSourceTreeInit class? (really don't know)
Thank you in advance,
-will
RE: Problem evaluating XPath expressions
Posted by Will Sappington <ws...@ndma.us>.
Hello Dave and all,
Prior to Dave posting the example below of how to initialize
Xalan/Xerces before instantiating library objects as member data, I
figured out a way of doing it that also works, described below. I'd
like to know if anyone has any thoughts regarding using a static member
function vs. as separate class as Dave describes below. I'm not so far
along that I couldn't switch if my method isn't good for some reason.
I'm aware of usability issues such as the static function requiring the
user to explicitly get/delete as opposed to just instantiating the
classes and letting them go out of scope. I'm more concerned with any
pitfalls this may cause in using the libraries, threading issues, and
the like. The get/delete methods do implement a counter and I'm
intending to go back and pthread_mutex them for thread safety. But
before I spend much more effort on this I'd like to know if I'm heading
down a dangerous path.
Thank you everyone for all your help these past couple of days.
-will
-----Original Message-----
From: Will Sappington [mailto:wsappington@ndma.us]
Sent: Wednesday, February 14, 2007 6:10 PM
To: xalan-c-users@xml.apache.org
Subject: RE: Problem evaluating XPath expressions
Dave, thank you very much for taking the time to do this. I followed up
my post below with another one later last night about an idea I hit upon
that is essentially what you are saying below. I'm using a static
member function, getInstance() that initializes the X libraries only on
the first call and then instantiates a Profile class with 'new' and
returns a pointer to the instance. As with your method below, the X
library initialization occurs before the parserLiaison constructs as
member data and everyone is happy. It appears to be working fine. I'll
read your suggestions below more thoroughly for things I could do to
improve my implementation.
Thanks again for all your help,
-will
-----Original Message-----
From: David Bertoni [mailto:dbertoni@apache.org]
Sent: Wednesday, February 14, 2007 4:28 PM
To: xalan-c-users@xml.apache.org
Subject: Re: Problem evaluating XPath expressions
Will Sappington wrote:
<snip>
Dave Bertoni wrote:
If you're going to do Xerces-C and Xalan-C initialization in the
constructor of your class, you'll need to create a simple class that
initializes Xerces-C and Xalan-C in the right order, and make that class
a
member of your class, ensuring that it appears before any other Xerces-C
or
Xalan-C class in the class definition. Here's an example, in
pseudo-code:
class XercesXalanInit
{
public:
XercesXalanInit()
{
if (++s_initCount == 1)
{
PlatformUtils::Initialize();
XalanTransformer::initialize();
}
}
~XercesXalanInit()
{
if (--s_initCount == 0)
{
XalanTransformer::terminate();
PlatformUtils::Terminate();
}
}
static unsigned long s_initCount;
};
XercesXalanInit::s_initCount = 0;
class myClass
{
public:
myClass() :
m_init(),
m_liason()
{
}
// all my public member functions here...
private:
XercesXalanInit m_init;
XalanSourceTreeParserLiaison m_liason;
};
Ultimately, it's much better if you initialize Xerces-C and Xalan-C
_once_,
when your application starts, and not when each instance is created.
Also,
you'll notice that I put some counting in the XercesXalanInit init
class,
because you should only call them each once. Finally, if your
application
will be multi-threaded, you will either need to initialize the libraries
once, before any threads start, or make the counting in XercesXalanInit
thread-safe.
Dave
RE: Problem evaluating XPath expressions
Posted by Will Sappington <ws...@ndma.us>.
Dave, thank you very much for taking the time to do this. I followed up
my post below with another one later last night about an idea I hit upon
that is essentially what you are saying below. I'm using a static
member function, getInstance() that initializes the X libraries only on
the first call and then instantiates a Profile class with 'new' and
returns a pointer to the instance. As with your method below, the X
library initialization occurs before the parserLiaison constructs as
member data and everyone is happy. It appears to be working fine. I'll
read your suggestions below more thoroughly for things I could do to
improve my implementation.
Thanks again for all your help,
-will
-----Original Message-----
From: David Bertoni [mailto:dbertoni@apache.org]
Sent: Wednesday, February 14, 2007 4:28 PM
To: xalan-c-users@xml.apache.org
Subject: Re: Problem evaluating XPath expressions
Will Sappington wrote:
> Hi Dave,
>
> I think I may have hit a dead end with this. When I define
> XalanSourceTreeParserLiaison _parserLiaison; as member data, the
program
> crashes with an assertion during construction of the Profile class.
The
> first line of the constructor doesn't even execute so the assertion is
> occurring in the construction of the member classes. I stepped into
it
> and found that it occurs during construction of the parserLiaison when
> it calls XalanMemMgrs::getDefaultXercesMemMgr() which is what
> XALAN_DEFAULT_MEMMGR is #defined as. After that call there is an
assert
> (ptr != 0) and that is where the crash occurs. I'm assuming this is
> because neither of the ::initialize() methods have been called. Of
> course there's no opportunity to do so prior to member data
construction
> so it would appear I'm screwed. Is there a way to instantiate a
memory
> manager such that the getDefaultXercesMemMgr() call would be able to
> find it?
If you're going to do Xerces-C and Xalan-C initialization in the
constructor of your class, you'll need to create a simple class that
initializes Xerces-C and Xalan-C in the right order, and make that class
a
member of your class, ensuring that it appears before any other Xerces-C
or
Xalan-C class in the class definition. Here's an example, in
pseudo-code:
class XercesXalanInit
{
public:
XercesXalanInit()
{
if (++s_initCount == 1)
{
PlatformUtils::Initialize();
XalanTransformer::initialize();
}
}
~XercesXalanInit()
{
if (--s_initCount == 0)
{
XalanTransformer::terminate();
PlatformUtils::Terminate();
}
}
static unsigned long s_initCount;
};
XercesXalanInit::s_initCount = 0;
class myClass
{
public:
myClass() :
m_init(),
m_liason()
{
}
// all my public member functions here...
private:
XercesXalanInit m_init;
XalanSourceTreeParserLiaison m_liason;
};
Ultimately, it's much better if you initialize Xerces-C and Xalan-C
_once_,
when your application starts, and not when each instance is created.
Also,
you'll notice that I put some counting in the XercesXalanInit init
class,
because you should only call them each once. Finally, if your
application
will be multi-threaded, you will either need to initialize the libraries
once, before any threads start, or make the counting in XercesXalanInit
thread-safe.
Dave
Re: Problem evaluating XPath expressions
Posted by David Bertoni <db...@apache.org>.
Will Sappington wrote:
> Hi Dave,
>
> I think I may have hit a dead end with this. When I define
> XalanSourceTreeParserLiaison _parserLiaison; as member data, the program
> crashes with an assertion during construction of the Profile class. The
> first line of the constructor doesn't even execute so the assertion is
> occurring in the construction of the member classes. I stepped into it
> and found that it occurs during construction of the parserLiaison when
> it calls XalanMemMgrs::getDefaultXercesMemMgr() which is what
> XALAN_DEFAULT_MEMMGR is #defined as. After that call there is an assert
> (ptr != 0) and that is where the crash occurs. I'm assuming this is
> because neither of the ::initialize() methods have been called. Of
> course there's no opportunity to do so prior to member data construction
> so it would appear I'm screwed. Is there a way to instantiate a memory
> manager such that the getDefaultXercesMemMgr() call would be able to
> find it?
If you're going to do Xerces-C and Xalan-C initialization in the
constructor of your class, you'll need to create a simple class that
initializes Xerces-C and Xalan-C in the right order, and make that class a
member of your class, ensuring that it appears before any other Xerces-C or
Xalan-C class in the class definition. Here's an example, in pseudo-code:
class XercesXalanInit
{
public:
XercesXalanInit()
{
if (++s_initCount == 1)
{
PlatformUtils::Initialize();
XalanTransformer::initialize();
}
}
~XercesXalanInit()
{
if (--s_initCount == 0)
{
XalanTransformer::terminate();
PlatformUtils::Terminate();
}
}
static unsigned long s_initCount;
};
XercesXalanInit::s_initCount = 0;
class myClass
{
public:
myClass() :
m_init(),
m_liason()
{
}
// all my public member functions here...
private:
XercesXalanInit m_init;
XalanSourceTreeParserLiaison m_liason;
};
Ultimately, it's much better if you initialize Xerces-C and Xalan-C _once_,
when your application starts, and not when each instance is created. Also,
you'll notice that I put some counting in the XercesXalanInit init class,
because you should only call them each once. Finally, if your application
will be multi-threaded, you will either need to initialize the libraries
once, before any threads start, or make the counting in XercesXalanInit
thread-safe.
Dave
RE: Problem evaluating XPath expressions
Posted by Will Sappington <ws...@ndma.us>.
Hi Dave,
I think I may have hit a dead end with this. When I define
XalanSourceTreeParserLiaison _parserLiaison; as member data, the program
crashes with an assertion during construction of the Profile class. The
first line of the constructor doesn't even execute so the assertion is
occurring in the construction of the member classes. I stepped into it
and found that it occurs during construction of the parserLiaison when
it calls XalanMemMgrs::getDefaultXercesMemMgr() which is what
XALAN_DEFAULT_MEMMGR is #defined as. After that call there is an assert
(ptr != 0) and that is where the crash occurs. I'm assuming this is
because neither of the ::initialize() methods have been called. Of
course there's no opportunity to do so prior to member data construction
so it would appear I'm screwed. Is there a way to instantiate a memory
manager such that the getDefaultXercesMemMgr() call would be able to
find it?
-will
-----Original Message-----
From: David Bertoni [mailto:dbertoni@apache.org]
Sent: Tuesday, February 13, 2007 3:01 PM
To: xalan-c-users@xml.apache.org
Subject: Re: Problem evaluating XPath expressions
Member variables are defined in the class definition, but not
initialized
there. Initialization occurs in the constructor, in the member
initialization list.
The reason the constructor that accepts the DOMSupport instance is
deprecated is because the XalanSourceTreeParserLiaison instance no
longer
needs the DOMSupport instance. You can simply use the constructor that
takes a MemoryManager instance, and use the default.
Dave
RE: Problem evaluating XPath expressions
Posted by Will Sappington <ws...@ndma.us>.
Thanks very much.
Re: member variable initialization - Doh, yeah, I knew that :-). The
parameterized constructor didn't register with me as an initialization.
Still making my way up the C++ learning curve.
-will
-----Original Message-----
From: David Bertoni [mailto:dbertoni@apache.org]
Sent: Tuesday, February 13, 2007 3:01 PM
To: xalan-c-users@xml.apache.org
Subject: Re: Problem evaluating XPath expressions
Member variables are defined in the class definition, but not
initialized
there. Initialization occurs in the constructor, in the member
initialization list.
The reason the constructor that accepts the DOMSupport instance is
deprecated is because the XalanSourceTreeParserLiaison instance no
longer
needs the DOMSupport instance. You can simply use the constructor that
takes a MemoryManager instance, and use the default.
Dave
Re: Problem evaluating XPath expressions
Posted by David Bertoni <db...@apache.org>.
Will Sappington wrote:
> Hi Dave, (sorry for the top-posting but OutHouse doesn't maintain the
> threading on emails very well so bottom-posting doesn't work very well.)
>
> I just got back to this and I'm having trouble implementing it. I moved
> the XalanSourceTreeInit and XalanSourceTreeParserLiaison instances to
> the private member data of the class and put the appropriate includes
> and "XALAN_USING_XALAN" statements at the top. These are the 4
> instances of Xalan member data:
>
> XalanDocument* _pXmlDoc; ///< ptr to the Xalan DOM document
> XalanSourceTreeDOMSupport _DomSupport;
>
> // Initialize the XalanSourceTree subsystem...
> XalanSourceTreeInit theSourceTreeInit;
> XalanSourceTreeParserLiaison theLiaison(_DomSupport);
>
> The compiler gives an error on the XalanSourceTreeParserLiaison
> declaration, specifically on the symbol _DomSupport. I'm not sure why
> this construction works inside as local function data and not as member
> data, but regardless, I looked up the XalanSourceTreeParserLiaison API
> for a different constructor and saw that this form has been deprecated.
> It now suggests the form that takes only a memory manager reference
> (defaulted to XALAN_DEFAULT_MEMMGR). I looked for a corresponding
> setter to set the DOMSupport instance but couldn't find one. What am I
> missing here? Thanks in advance for any help.
Member variables are defined in the class definition, but not initialized
there. Initialization occurs in the constructor, in the member
initialization list.
The reason the constructor that accepts the DOMSupport instance is
deprecated is because the XalanSourceTreeParserLiaison instance no longer
needs the DOMSupport instance. You can simply use the constructor that
takes a MemoryManager instance, and use the default.
Dave
RE: Problem evaluating XPath expressions
Posted by Will Sappington <ws...@ndma.us>.
Hi Dave, (sorry for the top-posting but OutHouse doesn't maintain the
threading on emails very well so bottom-posting doesn't work very well.)
I just got back to this and I'm having trouble implementing it. I moved
the XalanSourceTreeInit and XalanSourceTreeParserLiaison instances to
the private member data of the class and put the appropriate includes
and "XALAN_USING_XALAN" statements at the top. These are the 4
instances of Xalan member data:
XalanDocument* _pXmlDoc; ///< ptr to the Xalan DOM document
XalanSourceTreeDOMSupport _DomSupport;
// Initialize the XalanSourceTree subsystem...
XalanSourceTreeInit theSourceTreeInit;
XalanSourceTreeParserLiaison theLiaison(_DomSupport);
The compiler gives an error on the XalanSourceTreeParserLiaison
declaration, specifically on the symbol _DomSupport. I'm not sure why
this construction works inside as local function data and not as member
data, but regardless, I looked up the XalanSourceTreeParserLiaison API
for a different constructor and saw that this form has been deprecated.
It now suggests the form that takes only a memory manager reference
(defaulted to XALAN_DEFAULT_MEMMGR). I looked for a corresponding
setter to set the DOMSupport instance but couldn't find one. What am I
missing here? Thanks in advance for any help.
-will
-----Original Message-----
From: David Bertoni [mailto:dbertoni@apache.org]
Sent: Monday, February 12, 2007 1:50 AM
To: xalan-c-users@xml.apache.org
Subject: Re: Problem evaluating XPath expressions
Will Sappington wrote:
> Hello all,
>
>
>
> I'm writing a configuration utility that we call an "application
> profile" or simply profile, that is essentially an ini file on
> steroids. It's a hierarchical structure - application/section/item -
> that allows multiple applications to use a single profile. I'm
> migrating it from "key = value" format to XML and I'm using
Xalan/Xerces
> for evaluating XPath expressions to retrieve the configuration items.
>
...
>
> XalanDocumentPrefixResolver thePrefixResolver(_pXmlDoc);
>
>
>
> where _pXmlDoc is in the Profile class private member data
>
From looking at your code, I suspect the _pXmlDoc data member is
pointing
to an instance that's already been destroyed.
Here's what the comments for XMLParserLiason::parseXMLStream() say:
/**
* Parse the text pointed at by the reader as XML, and return a DOM
* Document interface. It is recommended that you pass in some sort of
* recognizable name, such as the filename or URI, with which the
reader
* can be recognized if the parse fails.
*
* The liaison owns the XalanDocument instance, and will delete it when
* when asked (see DestroyDocument()), or when the liaison is reset, or
* goes out of scope.
*/
So, the instance you created is destroyed when the
XalanSourceTreeParserLiaison instance is destroyed in
Profile::_openXmlDoc().
In general, Xalan-C implements very tightly controlled ownership of
objects. The easiest way for you to handle this is to make the
XalanSourceTreeParserLiason instance a member of your class.
Dave
Re: Problem evaluating XPath expressions
Posted by David Bertoni <db...@apache.org>.
Will Sappington wrote:
> Hello all,
>
>
>
> I’m writing a configuration utility that we call an “application
> profile” or simply profile, that is essentially an ini file on
> steroids. It’s a hierarchical structure – application/section/item –
> that allows multiple applications to use a single profile. I’m
> migrating it from “key = value” format to XML and I’m using Xalan/Xerces
> for evaluating XPath expressions to retrieve the configuration items.
>
...
>
> XalanDocumentPrefixResolver thePrefixResolver(_pXmlDoc);
>
>
>
> where _pXmlDoc is in the Profile class private member data
>
From looking at your code, I suspect the _pXmlDoc data member is pointing
to an instance that's already been destroyed.
Here's what the comments for XMLParserLiason::parseXMLStream() say:
/**
* Parse the text pointed at by the reader as XML, and return a DOM
* Document interface. It is recommended that you pass in some sort of
* recognizable name, such as the filename or URI, with which the reader
* can be recognized if the parse fails.
*
* The liaison owns the XalanDocument instance, and will delete it when
* when asked (see DestroyDocument()), or when the liaison is reset, or
* goes out of scope.
*/
So, the instance you created is destroyed when the
XalanSourceTreeParserLiaison instance is destroyed in Profile::_openXmlDoc().
In general, Xalan-C implements very tightly controlled ownership of
objects. The easiest way for you to handle this is to make the
XalanSourceTreeParserLiason instance a member of your class.
Dave