You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
610 lines
19 KiB
610 lines
19 KiB
|
|
/***************************************************************************
|
|
nodeview_cmds.c - node viewing commands for xsldbg
|
|
-------------------
|
|
begin : Wed Nov 21 2001
|
|
copyright : (C) 2001 by Keith Isdale
|
|
email : k_isdale@tpg.com.au
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "xsldbg.h"
|
|
#include <libxml/xpathInternals.h>
|
|
#include <libxml/HTMLparser.h>
|
|
#include <libxml/HTMLtree.h>
|
|
#include <ctype.h> /* for isspace*/
|
|
#include "debugXSL.h"
|
|
#include "arraylist.h"
|
|
#include "breakpoint.h"
|
|
#include "xsldbgmsg.h"
|
|
#include "xsldbgthread.h" /* for getThreadtqStatus */
|
|
#include "files.h"
|
|
#include "options.h"
|
|
|
|
|
|
/* -----------------------------------------
|
|
Private function declarations for nodeview_cmds.c
|
|
-------------------------------------------*/
|
|
static xmlChar nodeViewBuffer[500];
|
|
static int printVariableValue = 0;
|
|
|
|
/*
|
|
* xslDbgShellPrintNames:
|
|
* Print a name of variable found by scanning variable table
|
|
* It is used by print_variable function.
|
|
* @payload : not used
|
|
* @data : not used
|
|
* @name : the variable name
|
|
*/
|
|
void *xslDbgShellPrintNames(void *payload,
|
|
void *data, xmlChar * name);
|
|
|
|
/**
|
|
* xslDbgCatToFile:
|
|
* @node : Is valid
|
|
* @file : Is valid
|
|
*
|
|
* Send the results of cat command in @node to @file
|
|
*/
|
|
static void xslDbgCatToFile(xmlNodePtr node, FILE * file);
|
|
|
|
|
|
/**
|
|
* printXPathObject:
|
|
* @item : XPath object to print
|
|
* @xPath : The XPath used to find item
|
|
*
|
|
* Print an XPath object
|
|
*
|
|
* Returns 1 on success,
|
|
* 0 otherwise
|
|
*/
|
|
static int printXPathObject(xmlXPathObjectPtr item, xmlChar* xPath);
|
|
|
|
/* -------------------------------------
|
|
End private functions
|
|
---------------------------------------*/
|
|
|
|
|
|
/**
|
|
* xslDbgShellPrintList:
|
|
* @ctxt: The current shell context
|
|
* @arg: What xpath to display and in UTF-8
|
|
* @dir: If 1 print in dir mode?,
|
|
* otherwise ls mode
|
|
*
|
|
* Print list of nodes in either ls or dir format
|
|
*
|
|
* Returns 1 on success,
|
|
* 0 otherwise
|
|
*/
|
|
int
|
|
xslDbgShellPrintList(xmlShellCtxtPtr ctxt, xmlChar * arg, int dir)
|
|
{
|
|
xmlXPathObjectPtr list;
|
|
int result = 0;
|
|
|
|
if (!ctxt || !arg) {
|
|
#ifdef WITH_XSLDBG_DEBUG_PROCESS
|
|
xsltGenericError(xsltGenericErrorContext,
|
|
"Error: NULL arguments provided\n");
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
if (arg[0] == 0) {
|
|
if (dir)
|
|
xmlShellDir(ctxt, NULL, ctxt->node, NULL);
|
|
else
|
|
xmlShellList(ctxt, NULL, ctxt->node, NULL);
|
|
result = 1; /*assume that this worked */
|
|
} else {
|
|
ctxt->pctxt->node = ctxt->node;
|
|
ctxt->pctxt->node = ctxt->node;
|
|
if (!xmlXPathNsLookup(ctxt->pctxt, (xmlChar *) "xsl"))
|
|
xmlXPathRegisterNs(ctxt->pctxt, (xmlChar *) "xsl",
|
|
XSLT_NAMESPACE);
|
|
list = xmlXPathEval(arg, ctxt->pctxt);
|
|
if (list != NULL) {
|
|
switch (list->type) {
|
|
case XPATH_NODESET:{
|
|
int indx;
|
|
|
|
for (indx = 0;
|
|
indx < list->nodesetval->nodeNr; indx++) {
|
|
if (dir)
|
|
xmlShellList(ctxt, NULL,
|
|
list->nodesetval->
|
|
nodeTab[indx], NULL);
|
|
else
|
|
xmlShellList(ctxt, NULL,
|
|
list->nodesetval->
|
|
nodeTab[indx], NULL);
|
|
}
|
|
result = 1;
|
|
break;
|
|
}
|
|
default:
|
|
xmlShellPrintXPathError(list->type, (char *) arg);
|
|
}
|
|
xmlXPathFreeObject(list);
|
|
} else {
|
|
xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").tqarg(xsldbgText(arg)));
|
|
}
|
|
ctxt->pctxt->node = NULL;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* xslDbgCatToFile:
|
|
* @node : Is valid
|
|
* @file : Is valid
|
|
*
|
|
* Send the results of cat command in @node to @file
|
|
*/
|
|
void
|
|
xslDbgCatToFile(xmlNodePtr node, FILE * file)
|
|
{
|
|
if (!node || !file)
|
|
return;
|
|
|
|
/* assume that HTML usage is enabled */
|
|
if (node->doc->type == XML_HTML_DOCUMENT_NODE) {
|
|
if (node->type == XML_HTML_DOCUMENT_NODE)
|
|
htmlDocDump(file, (htmlDocPtr) node);
|
|
else
|
|
htmlNodeDumpFile(file, node->doc, node);
|
|
} else if (node->type == XML_DOCUMENT_NODE) {
|
|
/* turn off encoding for the moment and just dump UTF-8
|
|
* which will be converted by xsldbgGeneralErrorFunc */
|
|
xmlDocPtr doc = (xmlDocPtr) node;
|
|
const xmlChar *encoding = doc->encoding;
|
|
|
|
if (encoding) {
|
|
xsldbgGenericErrorFunc(i18n("Information: Temporarily setting document's encoding to UTF-8. Previously was %1.\n").tqarg(xsldbgText(encoding)));
|
|
}
|
|
doc->encoding = (xmlChar *) "UTF-8";
|
|
xmlDocDump(file, (xmlDocPtr) node);
|
|
doc->encoding = encoding;
|
|
} else {
|
|
xmlElemDump(file, node->doc, node);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* printXPathObject:
|
|
* @item : XPath object to print
|
|
* @xPath : The XPath used to find item
|
|
*
|
|
* Print an XPath object
|
|
*
|
|
* Returns 1 on success,
|
|
* 0 otherwise
|
|
*/
|
|
|
|
static int
|
|
printXPathObject(xmlXPathObjectPtr item, xmlChar* xPath){
|
|
int result = 0;
|
|
if (item){
|
|
switch (item->type) {
|
|
case XPATH_BOOLEAN:
|
|
xsltGenericError(xsltGenericErrorContext,
|
|
"= %s\n%s\n", xPath,
|
|
xmlBoolToText(item->boolval));
|
|
result = 1;
|
|
break;
|
|
|
|
case XPATH_NUMBER:
|
|
xsltGenericError(xsltGenericErrorContext,
|
|
"= %s\n%0g\n", xPath, item->floatval);
|
|
result = 1;
|
|
break;
|
|
|
|
/* case XPATH_NODESET:*/
|
|
default:{
|
|
/* We may need to convert this XPath to a string,
|
|
plus ensure that we print required the number of
|
|
lines of text */
|
|
int indx;
|
|
|
|
const char *fileName = filesTempFileName(0);
|
|
FILE *file = NULL;
|
|
|
|
if (!fileName)
|
|
break;
|
|
file = fopen(fileName, "w+");
|
|
if (!file) {
|
|
xsldbgGenericErrorFunc(i18n("Error: Unable to save temporary results to %1.\n").tqarg(xsldbgText(fileName)));
|
|
break;
|
|
} else {
|
|
fprintf(file, "= %s\n", xPath);
|
|
switch(item->type){
|
|
|
|
case XPATH_NODESET:
|
|
if (item->nodesetval){
|
|
for (indx = 0;
|
|
indx < item->nodesetval->nodeNr; indx++){
|
|
xslDbgCatToFile(item->nodesetval->
|
|
nodeTab[indx], file);
|
|
}
|
|
} else {
|
|
xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").tqarg(xsldbgText(xPath)));
|
|
}
|
|
break;
|
|
|
|
case XPATH_STRING:
|
|
if (item->stringval)
|
|
fprintf(file, "\'%s\'", item->stringval);
|
|
else
|
|
fprintf(file, "%s", i18n("NULL string value supplied.").utf8().data());
|
|
break;
|
|
|
|
default:{
|
|
xmlXPathObjectPtr tempObj =
|
|
xmlXPathObjectCopy(item);
|
|
if (tempObj)
|
|
tempObj = xmlXPathConvertString(tempObj);
|
|
if (tempObj && tempObj->stringval){
|
|
fprintf(file, "%s", tempObj->stringval);
|
|
}else{
|
|
fprintf(file, "%s", i18n("Unable to convert XPath to string.").utf8().data());
|
|
}
|
|
if (tempObj)
|
|
xmlXPathFreeObject(tempObj);
|
|
}
|
|
break;
|
|
fprintf(file,"\n");
|
|
|
|
} /* inner switch statement */
|
|
if (getThreadtqStatus() == XSLDBG_MSG_THREAD_RUN) {
|
|
fclose(file);
|
|
file = NULL;
|
|
/* send the data to application */
|
|
notifyXsldbgApp(XSLDBG_MSG_FILEOUT, fileName);
|
|
} else {
|
|
int lineCount = 0, gdbModeEnabled = 0;
|
|
|
|
/* save the value of option to speed things up
|
|
* a bit */
|
|
gdbModeEnabled =
|
|
optionsGetIntOption(OPTIONS_GDB);
|
|
rewind(file);
|
|
|
|
/* when gdb mode is enable then only print the first
|
|
* GDB_LINES_TO_PRINT lines */
|
|
while (!feof(file)) {
|
|
if (fgets
|
|
((char *) nodeViewBuffer, sizeof(nodeViewBuffer),
|
|
file))
|
|
xsltGenericError
|
|
(xsltGenericErrorContext, "%s",
|
|
nodeViewBuffer);
|
|
if (gdbModeEnabled) {
|
|
lineCount++;
|
|
/* there is an overhead of two lines
|
|
* when print expression values */
|
|
if (lineCount ==
|
|
GDB_LINES_TO_PRINT + 2) {
|
|
xsltGenericError
|
|
(xsltGenericErrorContext,
|
|
"...");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
xsltGenericError
|
|
(xsltGenericErrorContext, "\n");
|
|
}
|
|
if (file)
|
|
fclose(file);
|
|
result = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* xslDbgShellCat:
|
|
* @styleCtxt: the current stylesheet context
|
|
* @ctxt: The current shell context
|
|
* @arg: The xpath to print (in UTF-8)
|
|
*
|
|
* Print the result of an xpath expression. This can include variables
|
|
* if styleCtxt is not NULL
|
|
*
|
|
* Returns 1 on success,
|
|
* 0 otherwise
|
|
*/
|
|
|
|
int
|
|
xslDbgShellCat(xsltTransformContextPtr styleCtxt, xmlShellCtxtPtr ctxt,
|
|
xmlChar * arg)
|
|
{
|
|
xmlXPathObjectPtr list;
|
|
int result = 0;
|
|
static const char * TQUIET_STR = "-q";
|
|
bool silenceCtxtErrors = false;
|
|
|
|
if ((arg == NULL) || (xmlStrLen(arg) == 0))
|
|
arg = (xmlChar *) ".";
|
|
|
|
/* Do we quietly ingore style context errors */
|
|
if (strncasecmp((char*)arg, TQUIET_STR, strlen(TQUIET_STR))== 0){
|
|
silenceCtxtErrors = true;
|
|
arg = arg + strlen(TQUIET_STR);
|
|
while (isspace(*arg)){
|
|
arg++;
|
|
}
|
|
}
|
|
|
|
if (!styleCtxt || !ctxt || !ctxt->node) {
|
|
if (!(!xsldbgReachedFirstTemplate && silenceCtxtErrors))
|
|
xsldbgGenericErrorFunc(i18n("Warning: Unable to print expression. No stylesheet was properly loaded.\n"));
|
|
return 0;
|
|
}
|
|
|
|
if ((arg == NULL) || (xmlStrLen(arg) == 0))
|
|
arg = (xmlChar *) ".";
|
|
|
|
ctxt->pctxt->node = ctxt->node;
|
|
if (!styleCtxt) {
|
|
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
|
|
} else {
|
|
xmlNodePtr savenode = styleCtxt->xpathCtxt->node;
|
|
|
|
ctxt->pctxt->node = ctxt->node;
|
|
styleCtxt->xpathCtxt->node = ctxt->node;
|
|
if (!xmlXPathNsLookup(styleCtxt->xpathCtxt, (xmlChar *) "xsl"))
|
|
xmlXPathRegisterNs(styleCtxt->xpathCtxt, (xmlChar *) "xsl",
|
|
XSLT_NAMESPACE);
|
|
list = xmlXPathEval((xmlChar *) arg, styleCtxt->xpathCtxt);
|
|
styleCtxt->xpathCtxt->node = savenode;
|
|
}
|
|
if (list != NULL) {
|
|
result = printXPathObject(list, arg);
|
|
xmlXPathFreeObject(list);
|
|
} else {
|
|
xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").tqarg(xsldbgText(arg)));
|
|
}
|
|
ctxt->pctxt->node = NULL;
|
|
return result;
|
|
}
|
|
|
|
/* only used by xslDbgPrintNames and xslDbgPrintVariable cound number of variables */
|
|
static int varCount;
|
|
|
|
/*
|
|
* xslDbgShellPrintNames:
|
|
* Print a name of variable found by scanning variable table
|
|
* It is used by print_variable function.
|
|
* @payload : Global variable of type xsltStackElemPtr
|
|
* @data : not used
|
|
* @name : the variable name
|
|
*/
|
|
void *
|
|
xslDbgShellPrintNames(void *payload,
|
|
void *data, xmlChar * name)
|
|
{
|
|
Q_UNUSED(payload);
|
|
Q_UNUSED(data);
|
|
if (getThreadtqStatus() == XSLDBG_MSG_THREAD_RUN) {
|
|
notifyListQueue(payload);
|
|
} else if (payload && name) {
|
|
xmlChar * fullQualifiedName = nodeViewBuffer;
|
|
xsltStackElemPtr item = (xsltStackElemPtr)payload;
|
|
if (item->nameURI == NULL){
|
|
snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s", item->name);
|
|
}else{
|
|
snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s:%s",
|
|
item->nameURI, item->name);
|
|
}
|
|
if (printVariableValue == 0){
|
|
xsldbgGenericErrorFunc(i18n(" Global %1\n").tqarg(xsldbgText(fullQualifiedName)));
|
|
}else{
|
|
if (item->computed == 1){
|
|
xsldbgGenericErrorFunc(i18n(" Global "));
|
|
printXPathObject(item->value, fullQualifiedName);
|
|
}else if (item->tree){
|
|
xsldbgGenericErrorFunc(i18n(" Global = %1\n").tqarg(xsldbgText(fullQualifiedName)));
|
|
xslDbgCatToFile(item->tree, stderr);
|
|
}else if (item->select){
|
|
xsldbgGenericErrorFunc(i18n(" Global = %1\n%2").tqarg(xsldbgText(fullQualifiedName)).tqarg(xsldbgText(item->select)));
|
|
}else{
|
|
/* can't find a value give only a variable name an error message */
|
|
xsldbgGenericErrorFunc(i18n(" Global = %1\n%2").tqarg(xsldbgText(fullQualifiedName)).tqarg(i18n("Warning: No value assigned to variable.\n")));
|
|
}
|
|
xsltGenericError(xsltGenericErrorContext, "\n\032\032\n");
|
|
}
|
|
varCount++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* xslDbgShellPrintVariable:
|
|
* @styleCtxt: The current stylesheet context
|
|
* @arg: The name of variable to look for '$' prefix is optional and in UTF-8
|
|
* @type: A valid VariableTypeEnum
|
|
*
|
|
* Print the value variable specified by args.
|
|
*
|
|
* Returns 1 on success,
|
|
* 0 otherwise
|
|
*/
|
|
int
|
|
xslDbgShellPrintVariable(xsltTransformContextPtr styleCtxt, xmlChar * arg,
|
|
VariableTypeEnum type)
|
|
{
|
|
int result = 0;
|
|
/* command argument to include both name and its value */
|
|
static const char * FULLNAME_STR = "-f";
|
|
/* Quietly exit if an invalid stylesheet is provided */
|
|
static const char * TQUIET_STR = "-q";
|
|
bool silenceCtxtErrors = false;
|
|
|
|
if (!arg) {
|
|
#ifdef WITH_XSLDBG_DEBUG_PROCESS
|
|
xsltGenericError(xsltGenericErrorContext,
|
|
"Error: NULL argument provided\n");
|
|
#endif
|
|
return result;
|
|
}
|
|
|
|
varCount = 0;
|
|
/* Do we quietly ingore style context errors */
|
|
if (strncasecmp((char*)arg, TQUIET_STR, strlen(TQUIET_STR))== 0){
|
|
silenceCtxtErrors = true;
|
|
arg = arg + strlen(TQUIET_STR);
|
|
while (isspace(*arg)){
|
|
arg++;
|
|
}
|
|
}
|
|
|
|
if (!styleCtxt) {
|
|
if (!(!xsldbgReachedFirstTemplate && silenceCtxtErrors))
|
|
xsldbgGenericErrorFunc(i18n("Error: Debugger has no files loaded or libxslt has not reached a template.\nTry reloading files or taking more steps.\n"));
|
|
return result;
|
|
}
|
|
|
|
/* Do we include the name as well as its value */
|
|
if (strncasecmp((char*)arg, FULLNAME_STR, strlen(FULLNAME_STR))== 0){
|
|
printVariableValue = 1;
|
|
arg = arg + strlen(FULLNAME_STR);
|
|
while (isspace(*arg)){
|
|
arg++;
|
|
}
|
|
}
|
|
if (arg[0] == 0) {
|
|
/* list variables of type requested */
|
|
if (type == DEBUG_GLOBAL_VAR) {
|
|
if (styleCtxt->globalVars) {
|
|
if (getThreadtqStatus() == XSLDBG_MSG_THREAD_RUN) {
|
|
notifyListStart(XSLDBG_MSG_GLOBALVAR_CHANGED);
|
|
/* list global variables */
|
|
xmlHashScan(styleCtxt->globalVars,
|
|
(xmlHashScanner) xslDbgShellPrintNames,
|
|
NULL);
|
|
notifyListSend();
|
|
} else
|
|
/* list global variables */
|
|
xmlHashScan(styleCtxt->globalVars,
|
|
(xmlHashScanner) xslDbgShellPrintNames,
|
|
NULL);
|
|
result = 1;
|
|
/* ensure that the locals follow imediately after the
|
|
* globals when in gdb mode */
|
|
if (optionsGetIntOption(OPTIONS_GDB) == 0)
|
|
xsltGenericError(xsltGenericErrorContext, "\n");
|
|
} else {
|
|
if (getThreadtqStatus() != XSLDBG_MSG_THREAD_RUN) {
|
|
/* Don't show this message when running as a thread as it
|
|
* is annoying */
|
|
xsldbgGenericErrorFunc(i18n("Error: Libxslt has not initialized variables yet; try stepping to a template.\n"));
|
|
} else {
|
|
/* send an empty list */
|
|
notifyListStart(XSLDBG_MSG_GLOBALVAR_CHANGED);
|
|
notifyListSend();
|
|
result = 1;
|
|
}
|
|
}
|
|
} else {
|
|
/* list local variables */
|
|
if (styleCtxt->varsNr && styleCtxt->varsTab) {
|
|
if (getThreadtqStatus() == XSLDBG_MSG_THREAD_RUN) {
|
|
notifyListStart(XSLDBG_MSG_LOCALVAR_CHANGED);
|
|
for (int i = styleCtxt->varsNr; i > styleCtxt->varsBase; i--) {
|
|
xsltStackElemPtr item = styleCtxt->varsTab[i-1];
|
|
while (item) {
|
|
notifyListQueue(item);
|
|
item = item->next;
|
|
}
|
|
}
|
|
notifyListSend();
|
|
} else {
|
|
xmlChar * fullQualifiedName = nodeViewBuffer;
|
|
for (int i = styleCtxt->varsNr; i > styleCtxt->varsBase; i--) {
|
|
xsltStackElemPtr item = styleCtxt->varsTab[i-1];
|
|
while (item) {
|
|
if (item->name) {
|
|
if (item->nameURI == NULL){
|
|
snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s",
|
|
item->name);
|
|
}else{
|
|
|
|
snprintf((char*)fullQualifiedName, sizeof(nodeViewBuffer), "$%s:%s",
|
|
item->nameURI, item->name);
|
|
}
|
|
if (printVariableValue == 0){
|
|
xsldbgGenericErrorFunc(i18n(" Local %1").tqarg(xsldbgText(fullQualifiedName)));
|
|
}else{
|
|
if (item->computed == 1){
|
|
xsldbgGenericErrorFunc(i18n(" Local "));
|
|
printXPathObject(item->value, fullQualifiedName);
|
|
}else if (item->tree){
|
|
xsldbgGenericErrorFunc(i18n(" Local = %1\n").tqarg(xsldbgText(fullQualifiedName)));
|
|
xslDbgCatToFile(item->tree, stderr);
|
|
}else if (item->select){
|
|
xsldbgGenericErrorFunc(i18n(" Local = %1\n%2").tqarg(xsldbgText(fullQualifiedName)).tqarg(xsldbgText(item->select)));
|
|
}else{
|
|
/* can't find a value give only a variable name and an error */
|
|
xsldbgGenericErrorFunc(i18n(" Local = %1\n%2").tqarg(xsldbgText(fullQualifiedName)).tqarg(i18n("Warning: No value assigned to variable.\n")));
|
|
}
|
|
}
|
|
xsltGenericError(xsltGenericErrorContext, "\n\032\032\n");
|
|
}
|
|
item = item->next;
|
|
}
|
|
}
|
|
}
|
|
result = 1;
|
|
xsltGenericError(xsltGenericErrorContext, "\n");
|
|
} else {
|
|
if (getThreadtqStatus() != XSLDBG_MSG_THREAD_RUN) {
|
|
/* Don't show this message when running as a thread as it
|
|
* is annoying */
|
|
xsldbgGenericErrorFunc(i18n("Error: Libxslt has not initialized variables yet; try stepping past the xsl:param elements in the template.\n"));
|
|
} else {
|
|
/* send an empty list */
|
|
notifyListStart(XSLDBG_MSG_LOCALVAR_CHANGED);
|
|
notifyListSend();
|
|
result = 1;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
/* Display the value of variable */
|
|
if (arg[0] == '$') {
|
|
printXPathObject(xmlXPathEval(arg, styleCtxt->xpathCtxt), arg);
|
|
xsltGenericError(xsltGenericErrorContext, "\032\032\n");
|
|
} else {
|
|
xmlStrCpy(nodeViewBuffer, "$");
|
|
xmlStrCat(nodeViewBuffer, arg);
|
|
printXPathObject(xmlXPathEval((xmlChar*)nodeViewBuffer,styleCtxt->xpathCtxt),
|
|
(xmlChar*)nodeViewBuffer);
|
|
xsltGenericError(xsltGenericErrorContext, "\032\032\n");
|
|
}
|
|
|
|
}
|
|
|
|
printVariableValue = 0;
|
|
return result;
|
|
}
|