Make the XPath engine handle CDATA sections as text-nodes.
b=92786 r=peterv, pike sr=jst Mixed small fixes and comments. b=99792 r=peterv sr=jst git-svn-id: svn://10.0.0.236/trunk@103025 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -269,7 +269,8 @@ String* StringListIterator::next() {
|
||||
else {
|
||||
currentItem = stringList->firstItem;
|
||||
allowRemove = MB_TRUE;
|
||||
return currentItem->strptr;
|
||||
if (currentItem)
|
||||
return currentItem->strptr;
|
||||
}
|
||||
return 0;
|
||||
} //-- next
|
||||
|
||||
@@ -85,36 +85,12 @@ istream* URIUtils::getInputStream
|
||||
return inStream;
|
||||
|
||||
} //-- getInputStream
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns the document base of the href argument
|
||||
* @return the document base of the given href
|
||||
**/
|
||||
void URIUtils::getDocumentBase(const String& href, String& dest) {
|
||||
#ifndef TX_EXE
|
||||
String docBase("");
|
||||
nsCOMPtr<nsIURI> pURL;
|
||||
nsresult result = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIIOService> pService(do_GetService(NS_IOSERVICE_CONTRACTID,
|
||||
&result));
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
// XXX This is ugly, there must be an easier (cleaner way).
|
||||
char *uriStr = (((String)href).getConstNSString()).ToNewCString();
|
||||
result = pService->NewURI(uriStr, nsnull, getter_AddRefs(pURL));
|
||||
nsCRT::free(uriStr);
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
nsCOMPtr<nsIURL> tURL = do_QueryInterface(pURL);
|
||||
nsXPIDLCString temp;
|
||||
|
||||
tURL->SetFileName("");
|
||||
tURL->GetSpec(getter_Copies(temp));
|
||||
docBase = (const char *)temp;
|
||||
}
|
||||
}
|
||||
dest.append(docBase);
|
||||
#else
|
||||
//-- use temp str so the subString method doesn't destroy dest
|
||||
String docBase("");
|
||||
|
||||
@@ -138,8 +114,8 @@ void URIUtils::getDocumentBase(const String& href, String& dest) {
|
||||
delete uri;
|
||||
}
|
||||
dest.append(docBase);
|
||||
#endif
|
||||
} //-- getDocumentBase
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Resolves the given href argument, using the given documentBase
|
||||
|
||||
@@ -53,6 +53,7 @@ class URIUtils {
|
||||
|
||||
public:
|
||||
|
||||
#ifdef TX_EXE
|
||||
static const String HTTP_PROTOCOL;
|
||||
static const String FILE_PROTOCOL;
|
||||
|
||||
@@ -85,6 +86,7 @@ public:
|
||||
* The document base will be appended to the given dest String
|
||||
**/
|
||||
static void getDocumentBase(const String& href, String& dest);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Resolves the given href argument, using the given documentBase
|
||||
@@ -108,6 +110,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
#ifdef TX_EXE
|
||||
static const short PROTOCOL_MODE;
|
||||
static const short HOST_MODE;
|
||||
static const short PORT_MODE;
|
||||
@@ -124,8 +127,7 @@ private:
|
||||
|
||||
static istream* openStream(ParsedURI* uri);
|
||||
static ParsedURI* parseURI(const String& uri);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
}; //-- URIUtils
|
||||
|
||||
|
||||
@@ -114,6 +114,8 @@ double AttributeExpr::getDefaultPriority(Node* node, Node* context, ContextState
|
||||
**/
|
||||
MBool AttributeExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
|
||||
//XXX need to filter out namespace-declaration attributes!
|
||||
|
||||
if ( (!node) || (node->getNodeType() != Node::ATTRIBUTE_NODE) )
|
||||
return MB_FALSE;
|
||||
|
||||
@@ -159,7 +161,6 @@ MBool AttributeExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
* @return the String representation of this NodeExpr.
|
||||
**/
|
||||
void AttributeExpr::toString(String& dest) {
|
||||
dest.append('@');
|
||||
if (isNameWild && isNamespaceWild) dest.append('*');
|
||||
else {
|
||||
dest.append(this->prefix);
|
||||
|
||||
@@ -93,10 +93,10 @@ MBool BasicNodeExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
return (MBool)(node->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE &&
|
||||
!nodeNameSet || nodeName.isEqual(node->getNodeName()));
|
||||
default: //-- node()
|
||||
if (node->getNodeType() == Node::TEXT_NODE)
|
||||
if (node->getNodeType() == Node::TEXT_NODE ||
|
||||
node->getNodeType() == Node::CDATA_SECTION_NODE)
|
||||
return !cs->isStripSpaceAllowed(node);
|
||||
return MB_TRUE;
|
||||
break;
|
||||
}
|
||||
return MB_TRUE;
|
||||
} //-- matches
|
||||
|
||||
@@ -276,7 +276,7 @@ void LocationStep::toString(String& str) {
|
||||
str.append("ancestor-or-self::");
|
||||
break;
|
||||
case ATTRIBUTE_AXIS:
|
||||
str.append("attribute::");
|
||||
str.append("@");
|
||||
break;
|
||||
case DESCENDANT_AXIS:
|
||||
str.append("descendant::");
|
||||
|
||||
@@ -350,6 +350,7 @@ double NodeSet::numberValue() {
|
||||
**/
|
||||
void NodeSet::stringValue(String& str) {
|
||||
if ( size()>0) {
|
||||
// XXX Sort by document order here
|
||||
XMLDOMUtils::getNodeValue(get(0), &str);
|
||||
}
|
||||
} //-- stringValue
|
||||
|
||||
@@ -167,8 +167,10 @@ void PathExpr::evalDescendants (Expr* expr, Node* context,
|
||||
|
||||
Node* child = context->getFirstChild();
|
||||
while (child) {
|
||||
if (!(filterWS && (child->getNodeType() == Node::TEXT_NODE) &&
|
||||
XMLUtils::shouldStripTextnode(child->getNodeValue())))
|
||||
if (!(filterWS &&
|
||||
(child->getNodeType() == Node::TEXT_NODE ||
|
||||
child->getNodeType() == Node::CDATA_SECTION_NODE) &&
|
||||
XMLUtils::shouldStripTextnode(child->getNodeValue())))
|
||||
evalDescendants(expr, child, cs, resNodes);
|
||||
child = child->getNextSibling();
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ void StringResult::stringValue(String& str) {
|
||||
} //-- stringValue
|
||||
|
||||
MBool StringResult::booleanValue() {
|
||||
return (MBool)(this->value.length());
|
||||
return value.length() > 0;
|
||||
} //-- booleanValue
|
||||
|
||||
double StringResult::numberValue() {
|
||||
|
||||
@@ -33,19 +33,8 @@
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* TextExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
NodeSet* nodeSet = new NodeSet();
|
||||
|
||||
if ( !context ) return nodeSet;
|
||||
|
||||
Node* node = context->getFirstChild();
|
||||
while (node) {
|
||||
if ( node->getNodeType() == Node::TEXT_NODE )
|
||||
nodeSet->add(node);
|
||||
node = node->getNextSibling();
|
||||
}
|
||||
|
||||
return nodeSet;
|
||||
NS_ASSERTION(0, "TextExpr::evaluate called");
|
||||
return 0;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
@@ -61,8 +50,9 @@ double TextExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs)
|
||||
* the given context
|
||||
**/
|
||||
MBool TextExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
if ( node ) {
|
||||
if(node->getNodeType() == Node::TEXT_NODE)
|
||||
if (node) {
|
||||
if (node->getNodeType() == Node::TEXT_NODE ||
|
||||
node->getNodeType() == Node::CDATA_SECTION_NODE)
|
||||
return !cs->isStripSpaceAllowed(node);
|
||||
}
|
||||
return MB_FALSE;
|
||||
|
||||
@@ -804,6 +804,7 @@ MBool ProcessorState::isStripSpaceAllowed(Node* node) {
|
||||
break;
|
||||
}
|
||||
case Node::TEXT_NODE:
|
||||
case Node::CDATA_SECTION_NODE:
|
||||
if (!XMLUtils::shouldStripTextnode(node->getNodeValue()))
|
||||
return MB_FALSE;
|
||||
return isStripSpaceAllowed(node->getParentNode());
|
||||
@@ -954,6 +955,7 @@ ProcessorState::XMLSpaceMode ProcessorState::getXMLSpaceMode(Node* node) {
|
||||
break;
|
||||
}
|
||||
case Node::TEXT_NODE:
|
||||
case Node::CDATA_SECTION_NODE:
|
||||
//-- we will only see this the first time through the loop
|
||||
//-- if the argument node is a text node
|
||||
break;
|
||||
|
||||
@@ -960,7 +960,8 @@ void XSLTProcessor::processAction
|
||||
short nodeType = xslAction->getNodeType();
|
||||
|
||||
//-- handle text nodes
|
||||
if (nodeType == Node::TEXT_NODE) {
|
||||
if (nodeType == Node::TEXT_NODE ||
|
||||
nodeType == Node::CDATA_SECTION_NODE) {
|
||||
String textValue;
|
||||
if ( ps->isXSLStripSpaceAllowed(xslAction) ) {
|
||||
//-- strip whitespace
|
||||
@@ -968,7 +969,7 @@ void XSLTProcessor::processAction
|
||||
//-- I was thinking about removing whitespace while reading in the
|
||||
//-- XSL document, but this won't handle the case of Dynamic XSL
|
||||
//-- documents
|
||||
const String curValue = ((Text*)xslAction)->getData();
|
||||
const String curValue = xslAction->getNodeValue();
|
||||
|
||||
//-- set leading + trailing whitespace stripping flags
|
||||
#ifdef DEBUG_ah
|
||||
@@ -984,7 +985,7 @@ void XSLTProcessor::processAction
|
||||
else textValue=curValue;
|
||||
}
|
||||
else {
|
||||
textValue = ((Text*)xslAction)->getData();
|
||||
textValue = xslAction->getNodeValue();
|
||||
}
|
||||
//-- create new text node and add it to the result tree
|
||||
//-- if necessary
|
||||
@@ -1131,6 +1132,7 @@ void XSLTProcessor::processAction
|
||||
else {
|
||||
notifyError("missing required name attribute for xsl:call-template");
|
||||
}
|
||||
break;
|
||||
}
|
||||
// xsl:if
|
||||
case XSLType::CHOOSE :
|
||||
@@ -1249,7 +1251,11 @@ void XSLTProcessor::processAction
|
||||
{
|
||||
String selectAtt = actionElement->getAttribute(SELECT_ATTR);
|
||||
|
||||
if ( selectAtt.length() == 0 ) selectAtt = "*"; //-- default
|
||||
if (selectAtt.length() == 0)
|
||||
{
|
||||
notifyError("missing required select attribute for xsl:for-each");
|
||||
break;
|
||||
}
|
||||
|
||||
pExpr = ps->getPatternExpr(selectAtt);
|
||||
|
||||
@@ -1816,8 +1822,10 @@ void XSLTProcessor::processTemplateParams
|
||||
}
|
||||
else break;
|
||||
}
|
||||
else if (nodeType == Node::TEXT_NODE) {
|
||||
if (!XMLUtils::isWhitespace(((Text*)tmpNode)->getData())) break;
|
||||
else if (nodeType == Node::TEXT_NODE ||
|
||||
nodeType == Node::CDATA_SECTION_NODE) {
|
||||
if (!XMLUtils::isWhitespace(tmpNode->getNodeValue()))
|
||||
break;
|
||||
}
|
||||
tmpNode = tmpNode->getNextSibling();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user