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]

Reply via email to