Author: amassari
Date: Wed Jul 8 17:22:35 2009
New Revision: 792236
URL: http://svn.apache.org/viewvc?rev=792236&view=rev
Log:
Added methods defined in the Element Traversal specification
(http://www.w3.org/TR/2008/REC-ElementTraversal-20081222/)
Modified:
xerces/c/trunk/doc/readme.xml
xerces/c/trunk/src/xercesc/dom/DOMElement.hpp
xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.cpp
xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.hpp
xerces/c/trunk/tests/src/DOM/DOMTest/DTest.cpp
xerces/c/trunk/tests/src/DOM/DOMTest/DTest.h
Modified: xerces/c/trunk/doc/readme.xml
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/doc/readme.xml?rev=792236&r1=792235&r2=792236&view=diff
==============================================================================
--- xerces/c/trunk/doc/readme.xml (original)
+++ xerces/c/trunk/doc/readme.xml Wed Jul 8 17:22:35 2009
@@ -88,6 +88,8 @@
See <jump
href="program-dom-&XercesC3Series;.html#DOM3">DOM Level 3 Support</jump> for
detail.</li>
<li><jump
href="http://www.w3.org/TR/2006/REC-xinclude-20061115/">
XML Inclusions (XInclude) 1.0 (Second Edition)</jump>, W3C
Recommendation 15 November 2006</li>
+ <li><jump
href="http://www.w3.org/TR/2008/REC-ElementTraversal-20081222/">
+ Element Traversal Specification</jump>, W3C Recommendation
22 December 2008</li>
</ul>
<li>Source code, samples, and documentation is provided</li>
<li>Programmatic generation and validation of XML</li>
Modified: xerces/c/trunk/src/xercesc/dom/DOMElement.hpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/dom/DOMElement.hpp?rev=792236&r1=792235&r2=792236&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/dom/DOMElement.hpp (original)
+++ xerces/c/trunk/src/xercesc/dom/DOMElement.hpp Wed Jul 8 17:22:35 2009
@@ -58,6 +58,9 @@
* safely be used as a convenience.
*
* @since DOM Level 1
+ *
+ * It also defines the ElementTraversal helper interface defined by
http://www.w3.org/TR/2008/REC-ElementTraversal-20081222/
+ *
*/
class CDOM_EXPORT DOMElement: public DOMNode {
@@ -464,6 +467,57 @@
//@}
+ // -----------------------------------------------------------------------
+ // DOMElementTraversal interface
+ // -----------------------------------------------------------------------
+ /** @name Functions introduced in the ElementTraversal specification
(http://www.w3.org/TR/2008/REC-ElementTraversal-20081222/)*/
+ //@{
+ // -----------------------------------------------------------------------
+ // Getter methods
+ // -----------------------------------------------------------------------
+ /**
+ * The first child of type DOMElement.
+ *
+ * @return The <code>DOMElement</code> object that is the first element
node
+ * among the child nodes of this node, or <code>null</code> if there is
none.
+ */
+ virtual DOMElement * getFirstElementChild() const = 0;
+
+ /**
+ * The last child of type DOMElement.
+ *
+ * @return The <code>DOMElement</code> object that is the last element node
+ * among the child nodes of this node, or <code>null</code> if there is
none.
+ */
+ virtual DOMElement * getLastElementChild() const = 0;
+
+ /**
+ * The previous sibling node of type DOMElement.
+ *
+ * @return The <code>DOMElement</code> object that is the previous sibling
element node
+ * in document order, or <code>null</code> if there is none.
+ */
+ virtual DOMElement * getPreviousElementSibling() const = 0;
+
+ /**
+ * The next sibling node of type DOMElement.
+ *
+ * @return The <code>DOMElement</code> object that is the next sibling
element node
+ * in document order, or <code>null</code> if there is none.
+ */
+ virtual DOMElement * getNextElementSibling() const = 0;
+
+ /**
+ * The number of child nodes that are of type DOMElement.
+ *
+ * Note: the count is computed every time this function is invoked
+ *
+ * @return The number of <code>DOMElement</code> objects that are direct
children
+ * of this object (nested elements are not counted), or <code>0</code>
if there is none.
+ *
+ */
+ virtual XMLSize_t getChildElementCount() const = 0;
+ //@}
};
XERCES_CPP_NAMESPACE_END
Modified: xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.cpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.cpp?rev=792236&r1=792235&r2=792236&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.cpp (original)
+++ xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.cpp Wed Jul 8 17:22:35
2009
@@ -672,4 +672,191 @@
return &DOMTypeInfoImpl::g_DtdValidatedElement;
}
+// DOMElementTraversal
+DOMElement * DOMElementImpl::getFirstElementChild() const
+{
+ DOMNode* n = getFirstChild();
+ while (n != NULL) {
+ switch (n->getNodeType()) {
+ case DOMNode::ELEMENT_NODE:
+ return (DOMElement*) n;
+ case DOMNode::ENTITY_REFERENCE_NODE:
+ {
+ DOMElement* e = getFirstElementChild(n);
+ if (e != NULL)
+ return e;
+ }
+ break;
+ }
+ n = n->getNextSibling();
+ }
+ return NULL;
+}
+
+DOMElement * DOMElementImpl::getLastElementChild() const
+{
+ DOMNode* n = getLastChild();
+ while (n != NULL) {
+ switch (n->getNodeType()) {
+ case DOMNode::ELEMENT_NODE:
+ return (DOMElement*) n;
+ case DOMNode::ENTITY_REFERENCE_NODE:
+ {
+ DOMElement* e = getLastElementChild(n);
+ if (e != NULL)
+ return e;
+ }
+ break;
+ }
+ n = n->getPreviousSibling();
+ }
+ return NULL;
+}
+
+DOMElement * DOMElementImpl::getNextElementSibling() const
+{
+ DOMNode* n = getNextLogicalSibling(this);
+ while (n != NULL) {
+ switch (n->getNodeType()) {
+ case DOMNode::ELEMENT_NODE:
+ return (DOMElement*) n;
+ case DOMNode::ENTITY_REFERENCE_NODE:
+ {
+ DOMElement* e = getFirstElementChild(n);
+ if (e != NULL)
+ return e;
+ }
+ break;
+ }
+ n = getNextLogicalSibling(n);
+ }
+ return NULL;
+}
+
+DOMElement * DOMElementImpl::getPreviousElementSibling() const
+{
+ DOMNode* n = getPreviousLogicalSibling(this);
+ while (n != NULL) {
+ switch (n->getNodeType()) {
+ case DOMNode::ELEMENT_NODE:
+ return (DOMElement*) n;
+ case DOMNode::ENTITY_REFERENCE_NODE:
+ {
+ DOMElement* e = getLastElementChild(n);
+ if (e != NULL)
+ return e;
+ }
+ break;
+ }
+ n = getPreviousLogicalSibling(n);
+ }
+ return NULL;
+}
+
+XMLSize_t DOMElementImpl::getChildElementCount() const
+{
+ XMLSize_t count = 0;
+ DOMElement* child = getFirstElementChild();
+ while (child != NULL) {
+ ++count;
+ child = child->getNextElementSibling();
+ }
+ return count;
+}
+
+// Returns the first element node found from a
+// non-recursive in order traversal of the given node.
+DOMElement* DOMElementImpl::getFirstElementChild(const DOMNode* n) const
+{
+ const DOMNode* top = n;
+ while (n != NULL) {
+ if (n->getNodeType() == DOMNode::ELEMENT_NODE) {
+ return (DOMElement*) n;
+ }
+ DOMNode* next = n->getFirstChild();
+ while (next == NULL) {
+ if (top == n) {
+ break;
+ }
+ next = n->getNextSibling();
+ if (next == NULL) {
+ n = n->getParentNode();
+ if (n == NULL || top == n) {
+ return NULL;
+ }
+ }
+ }
+ n = next;
+ }
+ return NULL;
+}
+
+// Returns the first element node found from a
+// non-recursive reverse order traversal of the given node.
+DOMElement* DOMElementImpl::getLastElementChild(const DOMNode* n) const
+{
+ const DOMNode* top = n;
+ while (n != NULL) {
+ if (n->getNodeType() == DOMNode::ELEMENT_NODE) {
+ return (DOMElement*) n;
+ }
+ DOMNode* next = n->getLastChild();
+ while (next == NULL) {
+ if (top == n) {
+ break;
+ }
+ next = n->getPreviousSibling();
+ if (next == NULL) {
+ n = n->getParentNode();
+ if (n == NULL || top == n) {
+ return NULL;
+ }
+ }
+ }
+ n = next;
+ }
+ return NULL;
+}
+
+// Returns the next logical sibling with respect to the given node.
+DOMNode* DOMElementImpl::getNextLogicalSibling(const DOMNode* n) const
+{
+ DOMNode* next = n->getNextSibling();
+ // If "n" has no following sibling and its parent is an entity reference
node we
+ // need to continue the search through the following siblings of the
entity
+ // reference as these are logically siblings of the given node.
+ if (next == NULL) {
+ DOMNode* parent = n->getParentNode();
+ while (parent != NULL && parent->getNodeType() ==
DOMNode::ENTITY_REFERENCE_NODE) {
+ next = parent->getNextSibling();
+ if (next != NULL) {
+ break;
+ }
+ parent = parent->getParentNode();
+ }
+ }
+ return next;
+}
+
+// Returns the previous logical sibling with respect to the given node.
+DOMNode* DOMElementImpl::getPreviousLogicalSibling(const DOMNode* n) const
+{
+ DOMNode* prev = n->getPreviousSibling();
+ // If "n" has no previous sibling and its parent is an entity reference
node we
+ // need to continue the search through the previous siblings of the entity
+ // reference as these are logically siblings of the given node.
+ if (prev == NULL) {
+ DOMNode* parent = n->getParentNode();
+ while (parent != NULL && parent->getNodeType() ==
DOMNode::ENTITY_REFERENCE_NODE) {
+ prev = parent->getPreviousSibling();
+ if (prev != NULL) {
+ break;
+ }
+ parent = parent->getParentNode();
+ }
+ }
+ return prev;
+}
+
+
XERCES_CPP_NAMESPACE_END
Modified: xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.hpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.hpp?rev=792236&r1=792235&r2=792236&view=diff
==============================================================================
--- xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.hpp (original)
+++ xerces/c/trunk/src/xercesc/dom/impl/DOMElementImpl.hpp Wed Jul 8 17:22:35
2009
@@ -114,10 +114,23 @@
// helper function for DOM Level 3 renameNode
virtual DOMNode* rename(const XMLCh* namespaceURI, const XMLCh* name);
+ // DOMElementTraversal
+ virtual DOMElement * getFirstElementChild() const;
+ virtual DOMElement * getLastElementChild() const;
+ virtual DOMElement * getPreviousElementSibling() const;
+ virtual DOMElement * getNextElementSibling() const;
+ virtual XMLSize_t getChildElementCount() const;
+
protected:
// default attribute helper functions
virtual void setupDefaultAttributes();
+ // helper function for DOMElementTraversal methods
+ DOMElement* getFirstElementChild(const DOMNode* n) const;
+ DOMElement* getLastElementChild(const DOMNode* n) const;
+ DOMNode* getNextLogicalSibling(const DOMNode* n) const;
+ DOMNode* getPreviousLogicalSibling(const DOMNode* n) const;
+
private:
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
Modified: xerces/c/trunk/tests/src/DOM/DOMTest/DTest.cpp
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/tests/src/DOM/DOMTest/DTest.cpp?rev=792236&r1=792235&r2=792236&view=diff
==============================================================================
--- xerces/c/trunk/tests/src/DOM/DOMTest/DTest.cpp (original)
+++ xerces/c/trunk/tests/src/DOM/DOMTest/DTest.cpp Wed Jul 8 17:22:35 2009
@@ -946,6 +946,8 @@
delete parser;
OK = test.testLSExceptions();
+
+ OK = test.testElementTraversal();
}
XMLPlatformUtils::Terminate();
@@ -4955,6 +4957,127 @@
return true;
}
+bool DOMTest::testElementTraversal() {
+ const char* sXml="<?xml version='1.0'?>"
+ "<!DOCTYPE g ["
+ "<!ENTITY ent1 '<nestedEl>&ent2;</nestedEl>'>"
+ "<!ENTITY ent2 'text'>"
+ "]>"
+ "<g id='shapeGroup'>\n"
+ "\n"
+ "\t<rect id='rect1' x='5' y='5' width='310' height='220'
rx='15' ry='15' fill='skyblue'/>\n"
+ "\t<rect id='rect2' x='15' y='15' width='210' height='180'
rx='15' ry='15' fill='cornflowerblue'/>\n"
+ "\n"
+ "\t<ellipse id='ellipse1' cx='90' cy='70' rx='50' ry='30'
fill='yellow' stroke='orange'/>\n"
+ "\n"
+ "\t<path id='path1' stroke-width='15' stroke='orange'
fill='none' stroke-linecap='round'\n"
+ "\t\td='M25,150 C180,180 290,0 400,140 S420,100 460,90'/>\n"
+ "\t<text id='text1' x='0' y='0' font-size='35' fill='yellow'
stroke='orange'\n"
+ "\t\tstroke-width='2' stroke-linejoin='round'
font-weight='bold'>\n"
+ "\t\t<textPath id='textPath1'
xlink:href='#path1'>&ent1;&ent2;&ent1;</textPath></text>\n"
+ "</g>";
+ MemBufInputSource is((XMLByte*)sXml, strlen(sXml), "bufId");
+
+ static const XMLCh gLS[] = { chLatin_L, chLatin_S, chNull };
+ DOMImplementationLS *impl =
(DOMImplementationLS*)DOMImplementationRegistry::getDOMImplementation(gLS);
+ DOMLSParser *domBuilder =
impl->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
+ DOMLSInput *input = impl->createLSInput();
+ XMLString::transcode(sXml, tempStr, 3999);
+ input->setStringData(tempStr);
+ try
+ {
+ DOMDocument* doc=domBuilder->parse(input);
+
+ XMLSize_t c = doc->getDocumentElement()->getChildNodes()->getLength();
+ if(c!=11)
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ DOMNode* firstNode = doc->getDocumentElement()->getFirstChild();
+ if(firstNode==NULL || firstNode->getNodeType()!=DOMNode::TEXT_NODE ||
*firstNode->getNodeValue()=='\r')
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ DOMElement* childNode =
doc->getDocumentElement()->getFirstElementChild();
+ XMLString::transcode("id", tempStr, 3999);
+ XMLString::transcode("rect1", tempStr2, 3999);
+ if(childNode==NULL || childNode->getNodeType()!=DOMNode::ELEMENT_NODE
|| !XMLString::equals(childNode->getAttribute(tempStr),tempStr2))
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ XMLSize_t count=0;
+ while(childNode!=NULL)
+ {
+ count++;
+ childNode=childNode->getNextElementSibling();
+ }
+ if(count!=5)
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ count = doc->getDocumentElement()->getChildElementCount();
+ if(count!=5)
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ DOMElement* text=doc->getDocumentElement()->getLastElementChild();
+ XMLString::transcode("id", tempStr, 3999);
+ XMLString::transcode("text1", tempStr2, 3999);
+ if(text==NULL || text->getNodeType()!=DOMNode::ELEMENT_NODE ||
!XMLString::equals(text->getAttribute(tempStr),tempStr2))
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ DOMElement* textPath=text->getFirstElementChild();
+ XMLString::transcode("id", tempStr, 3999);
+ XMLString::transcode("textPath1", tempStr2, 3999);
+ if(textPath==NULL || textPath->getNodeType()!=DOMNode::ELEMENT_NODE ||
!XMLString::equals(textPath->getAttribute(tempStr),tempStr2))
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ count = textPath->getChildElementCount();
+ if(count!=2)
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ DOMElement* insideEntity=textPath->getFirstElementChild();
+ if(insideEntity==NULL ||
insideEntity->getNodeType()!=DOMNode::ELEMENT_NODE)
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ DOMElement* insideEntity2=textPath->getLastElementChild();
+ if(insideEntity2==NULL ||
insideEntity2->getNodeType()!=DOMNode::ELEMENT_NODE)
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ if(insideEntity->getNextElementSibling()!=insideEntity2 ||
insideEntity!=insideEntity2->getPreviousElementSibling())
+ {
+ fprintf(stderr, "checking ElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+ return true;
+ }
+ catch(DOMLSException&)
+ {
+ fprintf(stderr, "checking testElementTraversal failed at line %i\n",
__LINE__);
+ return false;
+ }
+
+ input->release();
+ domBuilder->release();
+
+ return true;
+}
+
/**
*
* @param node org.w3c.dom.DOMNode
Modified: xerces/c/trunk/tests/src/DOM/DOMTest/DTest.h
URL:
http://svn.apache.org/viewvc/xerces/c/trunk/tests/src/DOM/DOMTest/DTest.h?rev=792236&r1=792235&r2=792236&view=diff
==============================================================================
--- xerces/c/trunk/tests/src/DOM/DOMTest/DTest.h (original)
+++ xerces/c/trunk/tests/src/DOM/DOMTest/DTest.h Wed Jul 8 17:22:35 2009
@@ -108,6 +108,7 @@
bool testBaseURI(XercesDOMParser* parser);
bool testWholeText(XercesDOMParser* parser);
bool testLSExceptions();
+bool testElementTraversal();
bool testRegex();
};
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]