xml/xmldomandxpath/src/xmlenginedom/xmlengelement.cpp
changeset 0 e35f40988205
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xml/xmldomandxpath/src/xmlenginedom/xmlengelement.cpp	Thu Dec 17 09:29:21 2009 +0200
@@ -0,0 +1,1581 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Methods for element node
+//
+
+#include <xml/dom/xmlengelement.h>
+#include <xml/dom/xmlengdocument.h>
+#include <xml/dom/xmlengnamespace.h>
+#include <xml/dom/xmlengattr.h>
+#include <xml/dom/xmlengnodelist.h>
+#include <stdapis/libxml2/libxml2_globals.h>
+#include "xmlengdomdefs.h"
+#include <xml/utils/xmlengutils.h>
+#include <stdapis/libxml2/libxml2_parserinternals.h>
+#include <xml/utils/xmlengmem.h>
+#include <xml/utils/xmlengxestrings.h>
+#include "libxml2_tree_private.h"
+
+#define LIBXML_ELEMENT (static_cast<xmlNodePtr>(iInternal))
+
+void ResetNs(xmlNodePtr node,xmlNsPtr ns)
+    {
+    if(node->ns == ns)
+        {
+        node->ns = NULL;
+        }
+    xmlNodePtr child = node->children;
+    while (child)
+        {
+        if(child->type == XML_ELEMENT_NODE)
+            {
+            ResetNs(child,ns);
+            }
+        child = child->next;
+        }
+    xmlAttrPtr attr = node->properties;
+    while (attr)
+        {
+        if(attr->type == XML_ATTRIBUTE_NODE && attr->ns == ns)
+            {
+            attr->ns = NULL;
+            }
+        attr = attr->next;
+        }
+    };
+
+// ---------------------------------------------------------------------------------------------
+// Creates new attribute node out of any namespace (i.e. it has no prefix),
+// sets attribute's value and links it as the last attribute of the current element
+//   
+// @param  aName   A local name of attribute
+// @param  aValue  Value to set for new attribute or NULL (sets value to "")
+// @return         A handler to the newly created attribute node;
+//
+// For adding attribute as the first one, use TXmlEngNode::SetAsFirstSibling() on the attribute:
+// @code
+//     TXmlEngElement el = ... ; // get some element
+//     el.AddNewAttributeL("version","0.1").SetAsFirstSibling();
+// @endcode
+//   
+//   @see   SetAsLastSibling(), MoveBeforeSibling(TXmlEngNode) and MoveAfterSibling(TXmlEngNode)
+//
+//   @note   - No checks are made that attribute with such name exists
+//             Use this method only on newly created elements!
+//             Otherwise, use TXmlEngElement::SetAttributeL(..)
+//           - Attributes do not inherit default namespace of its element
+//             (http://w3.org/TR/REC-xml-names/#defaulting)
+//           - attribute's value is the second argument in all AddNewAttributeL(..) methods
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngAttr TXmlEngElement::AddNewAttributeL(
+    const TDesC8& aName,
+    const TDesC8& aValue )
+    {
+    if ( !iInternal )
+    	{
+    	User::Leave(KXmlEngErrNullNode);
+    	}
+    if ( aName.Length() <= 0 ) 
+    	{
+    	User::Leave(KXmlEngErrWrongUseOfAPI);
+    	}
+    //
+    xmlChar* name = xmlCharFromDesC8L(aName);
+    CleanupStack::PushL(name);
+    xmlChar* value = xmlCharFromDesC8L(aValue);
+    xmlAttrPtr attr = xmlNewProp( // NOTE: no checks that such attribute already exists
+                            LIBXML_ELEMENT,
+                            name,
+                            value);
+    delete value;
+    CleanupStack::PopAndDestroy(name);
+    OOM_IF_NULL(attr);
+    return TXmlEngNode(attr).AsAttr();
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Creates new attribute node and add it to the element
+//
+// Provided handle to namespace declaration is used to set up
+// attribute's namespace.
+//
+// @note If aNsDef is not defined in some of attributes ascendants
+//     (including this element), then
+//      ReconcileNamespacesL() method must be called on
+//      this element later.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngAttr  TXmlEngElement::AddNewAttributeL(
+    const TDesC8& aName,
+    const TDesC8& aValue,
+    TXmlEngNamespace aNsDef)
+    {
+    TXmlEngAttr attr = AddNewAttributeL(aName, aValue);
+    
+    _LIT(KAutoPrefix,"_pr%d");
+    const TInt KMaxPrefLength = 20;
+    TBuf<KMaxPrefLength> prefix;
+    
+    TUint ind = 0;
+    char* prefCh = NULL;
+    xmlNsPtr ns;
+    
+    if (aNsDef.NotNull())
+        {
+        if (aNsDef.IsDefault())
+            {
+            // create new temporary namespace binding (with non-NULL prefix)
+            ns = NULL;
+            while(!ns)
+                {
+                // generate prefix
+                ++ind;
+                prefix.Format(KAutoPrefix,ind);
+                prefCh = XmlEngXmlCharFromDesL(prefix);
+                TXmlEngConstString pref(prefCh);
+                delete prefCh;
+        		
+        		if(!xmlSearchNs(LIBXML_ELEMENT->doc,
+	        					LIBXML_ELEMENT,
+	        					CAST_DOMSTRING_TO_XMLCHAR(pref)))
+        			{
+	                ns = xmlNewNs(
+	                        LIBXML_ELEMENT,
+	                        INTERNAL_NSPTR(aNsDef)->href,
+	                        CAST_DOMSTRING_TO_XMLCHAR(pref));
+	                TEST_OOM_FLAG;        			
+        			}
+                }
+            }
+        else
+            {
+            ns = INTERNAL_NSPTR(aNsDef);
+            }
+        INTERNAL_ATTRPTR(attr)->ns = ns;
+        }
+    return attr;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Creates new attribute on the element. Namespace declaration for the attribute namespace is
+// created too.
+//
+// @note
+//     - Namespace declarations are reused if possible (no redundant ones are created)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngAttr TXmlEngElement::AddNewAttributeL(
+    const TDesC8& aName,
+    const TDesC8& aValue,
+    const TDesC8& aNsUri,
+    const TDesC8& aPrefix )
+    {
+    TXmlEngAttr attr = AddNewAttributeL(aName, aValue);
+    
+    if (!aPrefix.Length()) // NULL or "" 	 
+        {	  	 
+        if (aNsUri.Length()) // !(NULL or "") --> namespace URI is present
+            {
+            // An attribute cannot have default namespace (Pref = "" AND nsUri!="")
+	        WRONG_USE_OF_API;
+            }	  	 
+        return attr; 	  	  	 
+        }
+    
+    TXmlEngNamespace nsDef = AddNamespaceDeclarationL(aNsUri, aPrefix);
+    INTERNAL_ATTRPTR(attr)->ns = INTERNAL_NSPTR(nsDef);
+    return attr;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Creates new attributes using namespace, which is bound to the specified prefix
+//
+// Please, use this mothod only for construction of new parts of DOM tree, where
+// you know for sure that prefix is bound in the given scope.
+// @code
+//     TXmlEngElement el = parent.AddNewAttributeUsePrefixL("property","ObjName","rdf");
+//     el.AddNewAttributeUsePrefixL("type", "xs:integer", "rdf");
+// @endcode
+//
+// Otherwise, you should check that prefix is bound like this example shows:
+// @code
+//     TXmlEngNamespace boundNS = TXmlEngNamespace::LookupByPrefix(thisElement, prefix);
+//     if (boundNS.NotNull()){
+//         thisElement.AddNewAttributeUsePrefixL("name", value, prefix);
+//     }
+// @endcode
+//
+// @note
+//     Use AddNewAttributeNsL(name,value,nsDefNode) as much as you can, because
+//     it is most efficient way to create namespaced DOM elements (no additional
+//     lookups for namespace declarations are required).
+//   
+// @code
+//     // If namespace with given URI is not in the scope, then it will be declared
+//     // and bound to "data" prefix.
+//     TXmlEngNamespace nsDef = elem.FindOrCreateNsDeclL("http://../Data", "data");
+//     elem.AddNewAttributeL("location", "...", nsDef);
+//     elem.AddNewElementL("child", nsDef).AddNewAttributeL("attr","...value...");
+//     // the result is
+//        ...
+//        <elem xmlns:data="http://../Data" data:location="...">
+//           <data:child attr="...value..."/>
+//        </elem>
+//        ...
+//     //
+// @endcode    
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngAttr TXmlEngElement::AddNewAttributeUsePrefixL(
+    const TDesC8& aLocalName,
+    const TDesC8& aValue,
+    const TDesC8& aPrefix )
+    {
+    _LIT8(KXml,"xml");
+    TXmlEngAttr attr = AddNewAttributeL(aLocalName, aValue);
+    // try to locate namespace binding for the same prefix
+    xmlChar* prefix = xmlCharFromDesC8L(aPrefix);
+    xmlNsPtr ns = xmlSearchNs(
+                    LIBXML_ELEMENT->doc,
+                    LIBXML_ELEMENT,
+                    prefix);
+    delete prefix;                
+    
+    if (!ns)
+        {
+        // OOM may happen ONLY for "xml" prefix search
+        OOM_IF(!aPrefix.Compare(KXml));
+        WRONG_USE_OF_API; // Prefix is not bound
+        }
+    INTERNAL_ATTRPTR(attr)->ns = ns;
+    return attr;
+}
+
+// ---------------------------------------------------------------------------------------------
+// Creates new attributes using namespace in the scope, which has specified URI
+//   
+// Almost the same as AddNewAttributeUsePrefixL(...) but does lookup by namespace URI
+//
+// @return - NULL attribute if namespace declaration is not found OR newly added to the end of
+//     attribute list attribute of this element.
+//
+// @see AddNewAttributeUsePrefixL(TDesC8,TDesC8,TDesC8)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngAttr TXmlEngElement::AddNewAttributeWithNsL(
+    const TDesC8& aLocalName,
+    const TDesC8& aValue,
+    const TDesC8& aNsUri )
+    {
+    _LIT8(KXmlNs,"http://www.w3.org/XML/1998/namespace");
+    // try to locate namespace binding for the same prefix
+    xmlChar* nsp = xmlCharFromDesC8L(aNsUri);
+    xmlNsPtr ns = xmlSearchNsByHref(
+                    LIBXML_ELEMENT->doc,
+                    LIBXML_ELEMENT,
+                    nsp);
+    delete nsp;
+    
+    if (!ns)
+        {
+        // OOM may happen ONLY for "xml" prefix search
+        OOM_IF(!aNsUri.Compare(KXmlNs));
+        TXmlEngAttr attr;
+        return attr;
+        }
+    
+    TXmlEngAttr attr = AddNewAttributeL(aLocalName, aValue);
+        
+    INTERNAL_ATTRPTR(attr)->ns = ns;
+    return attr;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Adds child element with no namespace
+//
+// @param aName name of the element
+//
+// Results in adding element with aName and no prefix.
+//
+// This method is the best for creation of non-namespace based documents
+// or document fragments, where no default namespace declared.
+//
+// It may be used also as a method for  adding element from default namespace,
+// BUT namespace will be assigned ONLY after serialization of the current
+// document and parsing it back into a DOM tree!! If you need that default namespace
+// was inherited by new element immediately use:
+// @code
+//     ...
+//     TXmlEngNamespace defns = element.DefaultNamespace();
+//     TXmlEngElement newEl = element.AddNewElementL("Name",defns);
+//     ...
+// @endcode
+//
+// If truly undefined namespace for the element is required, then <b>DO NOT USE</b>
+// this method if there is a default namespace in the scope!
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement TXmlEngElement::AddNewElementL(
+    const TDesC8& aName )
+    {
+    if ( !iInternal )
+    	{
+    	User::Leave(KXmlEngErrNullNode);
+    	}
+    if ( aName.Length() <= 0 ) 
+    	{
+    	User::Leave(KXmlEngErrWrongUseOfAPI);
+    	}
+    xmlChar* name = xmlCharFromDesC8L(aName);
+    xmlNodePtr element = xmlNewNode(NULL, name);
+    delete name;
+    //
+    OOM_IF_NULL(element);
+    //
+    element->parent = LIBXML_ELEMENT;
+    element->doc = LIBXML_ELEMENT->doc;
+    // Link element as the last child
+    xmlNodePtr prev = LIBXML_ELEMENT->last;
+    LIBXML_ELEMENT->last = element;
+    element->prev = prev;
+    if (prev)
+        {
+        prev->next = element;
+        }
+    if (!(LIBXML_ELEMENT->children))
+        {
+        LIBXML_ELEMENT->children = element;
+        }
+    return TXmlEngElement(element);
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Creates new child element with provided name, prefix and namespace URI
+//
+// New namespace declaration will be attached to the parent (this) element and used
+// as namespace for newly created child element. If such binding already exists
+// (same prefix is bound to same URI), it will be reused. If the prefix is already
+// bound to some another namespace URI, it will be rebound by the new namespace
+// declaration node.
+//
+// @param aLocalName Name of the element
+// @param aNsUri     URI of element's namespace
+// @param aPrefix    Prefix of the element
+// @return Created element node (and added as the last child of its parent)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement TXmlEngElement::AddNewElementL(
+    const TDesC8& aLocalName,
+    const TDesC8& aNsUri,
+    const TDesC8& aPrefix )
+    {
+    TXmlEngElement element = AddNewElementL(aLocalName);
+    TXmlEngNamespace nsDef = AddNamespaceDeclarationL(aNsUri, aPrefix);
+    INTERNAL_NODEPTR(element)->ns = INTERNAL_NSPTR(nsDef);
+    return element;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Creates new child element with provided name and namespace declaration
+//
+// @param aLocalName Name of the element
+// @param aNsDef     Handle of the namespace declaration, that must be retrieved from
+//                  one of the ascendant nodes of the new elements (and its prefix
+//                  should not be remapped to another namespace URI for the scope
+//                  of the new element)
+// @return    Created element node (and added as the last child of its parent)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement  TXmlEngElement::AddNewElementL(
+    const TDesC8& aLocalName,
+    TXmlEngNamespace aNsDef )
+    {
+    TXmlEngElement element = AddNewElementL(aLocalName);
+    INTERNAL_NODEPTR(element)->ns = INTERNAL_NSPTR(aNsDef);
+    return element;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Adds child element with same namespace (and prefix if present) as parent element has
+//
+// @param aLocalName element's name
+// @return New element that was added to the end of children list of its parent (this element)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement TXmlEngElement::AddNewElementSameNsL(
+    const TDesC8& aLocalName )
+    {
+    TXmlEngElement element = AddNewElementL(aLocalName);
+    INTERNAL_NODEPTR(element)->ns = LIBXML_ELEMENT->ns;
+    return element;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Performs lookup for the namespace declaration for specified prefix and
+// adds new child element with found namespace.
+//
+// The assumption is that prefix is bound, otherwise run-time error
+// (Symbian's Leave or exception) occurs
+//
+// @note   Use this method only if there is a binding for the given prefix.
+//
+// @param aLocalName element's name
+// @param aPrefix    prefix to use
+// @return new TXmlEngElement that was added to the end of children list of its parent (this element)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement TXmlEngElement::AddNewElementUsePrefixL(
+    const TDesC8& aLocalName,
+    const TDesC8& aPrefix )
+    {
+    _LIT8(KXml,"xml");
+    TXmlEngElement element = AddNewElementL(aLocalName);
+    // Can fail only with XML's namespace
+    xmlChar* pref = xmlCharFromDesC8L(aPrefix);
+    xmlNsPtr ns = xmlSearchNs(
+                    LIBXML_ELEMENT->doc,
+                    LIBXML_ELEMENT,
+                    pref);
+    delete pref;
+    //
+    OOM_IF(!ns && !aPrefix.Compare(KXml));
+    //
+    INTERNAL_NODEPTR(element)->ns = ns;
+    return element;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Performs lookup for the namespace declaration for specified namespace URI and
+// adds new child element with found namespace.
+//
+// The assumption is that namespace with given URI was declared,
+// otherwise run-time error (Symbian' Leave or exception) occurs
+//
+// @note Use this method only if namespace declaration for the provided URI exists.
+//
+// @param aLocalName element's name
+// @param aNsUri     namespace of element
+// @return new TXmlEngElement that was added to the end of children list of its parent (this element)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement TXmlEngElement::AddNewElementWithNsL(
+    const TDesC8& aLocalName,
+    const TDesC8& aNsUri )
+    {
+    _LIT8(KXmlNs,"http://www.w3.org/XML/1998/namespace");
+    TXmlEngElement element = AddNewElementL(aLocalName);
+    /*xmlNsPtr ns = xmlSearchNsByHref(
+                    LIBXML_ELEMENT->doc,
+                    LIBXML_ELEMENT,
+                    CAST_DOMSTRING_TO_XMLCHAR(aNsUri));
+    */
+    TXmlEngNamespace ns = LookupNamespaceByUriL(aNsUri);
+    // May fail only with XML's namespace
+    OOM_IF(ns.IsNull() && !aNsUri.Compare(KXmlNs));
+    //
+    INTERNAL_NODEPTR(element)->ns = INTERNAL_NSPTR(ns);
+    return element;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Creates new child element; if there is no a prefix binding for new element's namespace,
+// a namespace decaration is created with generated prefix at specified element.
+//
+// @param aLocalName    Name of the element to create
+// @param aNsUri        Namespace URI of the new element
+// @param aNsDeclTarget An element where namespace declaraton should be placed
+//                     if there is a needed to create new namespace declaration;
+//                     NULL is used to specify the created element itself
+//
+// As aNsDeclTarget any ascendant of the new node may be provided:
+// @code
+//     el.AddNewElementAutoPrefixL(tagName,uri,NULL); // declare on the new element
+//     el.AddNewElementAutoPrefixL(tagName,uri,el);   // declare on the parent element
+//     el.AddNewElementAutoPrefixL(tagName,uri,doc.DocumentElement()); // declare on the root element
+//     ...
+// @endcode
+//
+// @note
+//     The farther namespace declaration up in the document tree,
+//     the longer time namespace declaration lookups take.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement TXmlEngElement::AddNewElementAutoPrefixL(
+    const TDesC8& aLocalName,
+    const TDesC8& aNsUri,
+    TXmlEngElement aNsDeclTarget )
+    {
+    TXmlEngElement elem = AddNewElementL(aLocalName);
+    if (aNsDeclTarget.IsNull())
+        aNsDeclTarget = elem;
+    TXmlEngNamespace ns = aNsDeclTarget.FindOrCreateNsDeclL(aNsUri);
+    INTERNAL_NODEPTR(elem)->ns = INTERNAL_NSPTR(ns);
+    return elem;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Retrieves list of attribute nodes of the element
+//   
+// @param aList - a node list object to initialize
+//
+// Passed by reference list of nodes is initialized and after call to
+// Attributes(..) is ready for use with HasNext() and Next() methods:
+//
+// @code
+//     ...
+//     TXmlEngElement root = doc.DocumentElement();
+//     TXmlEngNodeList<TXmlEngAttr>    attlist;
+//     root.GetAttributes(attlist);
+//     while (attlist.HasNext())
+//           processAttribute(attlist.Next());
+//     ...
+// @endcode
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::GetAttributes(
+    RXmlEngNodeList<TXmlEngAttr>& aList ) const
+    {
+    //pjj18
+    aList.Open( LIBXML_ELEMENT->properties,
+                  TXmlEngNode::EAttribute);
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Retrieves list of child elements of the element
+//
+// @param aList - a node list object to initialize
+//
+// Passed by reference list of nodes is initialized and after the call
+// it is ready for use with HasNext() and Next() methods:
+//   
+// @note Returned list is a "filtered view" of the underlying
+//     list of all element's children (with text nodes, comments
+//     processing instructions, etc.)
+// ---------------------------------------------------------------------------------------------
+//  
+EXPORT_C void TXmlEngElement::GetChildElements(
+    RXmlEngNodeList<TXmlEngElement>& aList ) const
+    {
+    //pjj18
+    aList.Open( LIBXML_ELEMENT->children,
+                  TXmlEngNode::EElement);
+    }
+
+// ---------------------------------------------------------------------------------------------
+// @return Basic contents of the element
+//
+// This method may be used in most cases, when element has only simple text content
+// (without entity references embedded)
+//
+// If element's contents is mixed (other types of nodes present), only contents of
+// first child node is returned if it is a TXmlEngTextNode node. For getting mixed contents of the
+// element of contents with entity references, WholeTextValueCopyL() should be used.
+//
+// @see TXmlEngNode::WholeTextContentsCopyL()
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TPtrC8 TXmlEngElement::Text() const
+    {
+    if (LIBXML_ELEMENT && LIBXML_ELEMENT->children && LIBXML_ELEMENT->children->type == XML_TEXT_NODE)
+        {
+        return ((TXmlEngConstString)CAST_XMLCHAR_TO_DOMSTRING(LIBXML_ELEMENT->children->content)).PtrC8();
+        }
+    return KNullDesC8();
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Adds text as a child of the element.
+//
+// At the moment, content may be only added, replaced (set) and read from element.
+//
+// @param aString text to be added as element's content.
+//
+// @note There may be several TXmlEngTextNode and TXmlEngEntityReference nodes added actually,
+//      depending on the aString value
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::AddTextL(
+    const TDesC8& aString )
+    {
+    if ( !LIBXML_ELEMENT )
+    	{
+    	User::Leave(KXmlEngErrNullNode);
+    	}
+    //
+    xmlNodePtr last, newNode, tmp;
+    last = LIBXML_ELEMENT->last;
+    xmlChar* text = xmlCharFromDesC8L(aString);
+    newNode = xmlNewTextLen(NULL, aString.Size());
+    if(!newNode)
+        {
+        delete text;
+        OOM_HAPPENED;
+        }
+    newNode->content = text;
+
+    tmp = xmlAddChild(LIBXML_ELEMENT, newNode);
+    if (xmlOOMFlag())
+        {
+        xmlFreeNode(newNode);
+        OOM_HAPPENED;
+        }
+
+    if (tmp == newNode &&
+        last && last->next == newNode)
+        {
+        OOM_IF_NULL(xmlTextMerge(last, newNode));
+        }
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Ad Xml:Id attribute to the element
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngAttr TXmlEngElement::AddXmlIdL(const TDesC8& aLocalName,
+                                   const TDesC8& aValue,
+                                   TXmlEngNamespace aNs)
+    {
+    if(IsNull())
+    	{
+        User::Leave(KXmlEngErrWrongUseOfAPI);
+    	}
+    
+    TXmlEngAttr attr;
+    xmlChar* value = xmlCharFromDesC8L(aValue);
+    xmlAttrPtr tmp = xmlGetID(LIBXML_ELEMENT->doc, value);
+    if(tmp)
+        {
+        delete value;
+        return attr;
+        }
+    
+    attr = AddNewAttributeL(aLocalName, aValue);
+    if(aNs.NotNull())
+        {
+        TXmlEngNamespace tmp = LookupNamespaceByPrefixL(aNs.Prefix());
+        if(!tmp.IsSameNode(aNs))
+            {
+            attr.Remove();
+            delete value;
+            return attr;
+            }
+        INTERNAL_ATTRPTR(attr)->ns = INTERNAL_NSPTR(aNs);
+        }
+    
+    if(attr.IsNull())
+        {
+        User::Leave(KXmlEngErrWrongUseOfAPI);
+        }
+        
+    if(!xmlAddID(NULL, LIBXML_ELEMENT->doc, value, INTERNAL_ATTRPTR(attr)))
+        {
+        delete value;
+        attr.Remove();
+        XmlEngOOMTestL();
+        }
+    delete value;
+    return attr;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Sets text contents for the element.
+// Any child nodes are removed.
+// Same as TXmlEngNode::SetValueL(const TDesC8&)
+//
+// @see TXmlEngNode::SetValueL(const TDesC8&)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::SetTextL(const TDesC8& aString)
+    {
+    AsAttr().SetValueL(aString);
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Sets text content of the element from escaped string.
+// @see TXmlEngAttr::SetEscapedValueL(const TDesC8&)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::SetEscapedTextL(const TDesC8& aEscapedString)
+    {
+    AsAttr().SetEscapedValueL(aEscapedString);
+    }
+
+
+// -------------------------------------------------------------------------------------
+// Sets new element value exactly as presented in the string.
+// Predefined entities are not converted into characters they represent.
+// Any child nodes are removed.
+// -------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::SetTextNoEncL(const TDesC8& aNotEncString)
+	{
+    AsAttr().SetValueNoEncL(aNotEncString);	
+	}
+
+// -------------------------------------------------------------------------------------
+// Appends new text node with the value exactly as presented in the string.
+// Predefined entities are not converted into characters they represent.
+// Child nodes are not removed.  
+// -------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::AppendTextNoEncL(const TDesC8& aNotEncString)
+	{
+    if ( !LIBXML_ELEMENT )
+    	{
+    	User::Leave(KXmlEngErrNullNode);
+    	}
+
+    xmlNodePtr prop = LIBXML_ELEMENT;
+    xmlNodePtr new_ch;
+
+	if (aNotEncString.Length())
+        {
+		xmlChar* value = xmlCharFromDesC8L(aNotEncString);
+        new_ch = xmlNewText(NULL);
+        if(!new_ch)
+            {
+            delete value;
+            OOM_HAPPENED;
+            };
+
+        new_ch->name = xmlStringTextNoenc;
+        new_ch->content = value;
+        new_ch->parent = (xmlNodePtr) prop;
+       	xmlNodePtr last = prop->last;
+       	if(last)
+       		{
+       		last->next = new_ch;
+       		new_ch->prev = last;
+       		}
+       	else
+       		{
+       		prop->children = new_ch;
+       		}
+       	prop->last = new_ch;
+        }   
+	}
+	
+	
+// ---------------------------------------------------------------------------------------------
+// Adds default namespace declaration.
+//
+// @param aNsUri   Namespace URI;  both NULL and "" (empty string) are allowed to represent UNDEFINED NAMSPACE
+//
+// Same result as with AddNamespaceDeclarationL(aNsUri, NULL), but additionally
+// element's namespace modified (if it has no prefix and there were no default
+// namespace declaration in the scope) to the new default one.
+//
+// @return Handle to the created namespace declaration (NULL for UNDEFINED NAMESPACE)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngNamespace TXmlEngElement::SetDefaultNamespaceL(
+    const TDesC8& aNsUri)
+    {
+    TXmlEngNamespace nsDef = AddNamespaceDeclarationL(aNsUri,KNullDesC8);
+    if (!LIBXML_ELEMENT->ns)
+        LIBXML_ELEMENT->ns = INTERNAL_NSPTR(nsDef);
+    return nsDef;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Undeclares any default namespace for current element and its descendants.
+//
+// If there is already some default namespace,  <i>xmlns=""</i> namespace
+// declaration is added. Otherwise, nothing happens, since element with no
+// prefix in such scope is automaticaly considered as out of any namespace.
+//
+// The side effect of this method is that namespace of the current element
+// may change from previous <b>default</b> namespace to NULL TXmlEngNamespace, which is
+// considered an absence of namespace.
+//
+// If the element has prefix (i.e. not having default namespace), 
+// then the only effect for the element is undeclaration of existing default namespace. 
+//
+// If element is in the scope of another <i>xmlns=""</i> undeclaration, no
+// actions are taken.
+//
+// @note
+//     Use AddNamespaceDeclarationL(NULL,NULL) to force creation of
+//     xmlns=""  declaration within scope of another such declaration 
+//     (otherwise unneccessary/duplicate declarations are not created)
+//
+// @note
+//     This method should be called on elements before adding children,
+//     because default namespace undeclaration is not spread into its subtree and 
+//     descedants' default namespaces are not reset to NULL. This should be taken into 
+//     account if later some processing on the subtree occurs.
+//     However, after serialization and deserialization, undeclared default namespace will
+//     affect whole element's subtree correctly.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::SetNoDefaultNamespaceL()
+    {
+    if ( !LIBXML_ELEMENT )
+    	{
+    	User::Leave(KXmlEngErrNullNode);
+    	}
+    //
+    TXmlEngNamespace defns = LookupNamespaceByPrefixL(KNullDesC8);
+    if (defns.IsUndefined()) // NULL or Uri is NULL
+        {
+        // we are already in the scope of xmlns="" , so do nothing
+        return;
+        }
+
+    // There is some default namespace in the scope.
+    // Add local "undefined" namespace and change element's namespace
+    // if it is the default one
+    AddNamespaceDeclarationL(KNullDesC8, KNullDesC8);
+    TXmlEngNamespace myNs(LIBXML_ELEMENT->ns);
+    if (myNs.IsDefault())
+        {
+        // replace default namespace with undefined
+        LIBXML_ELEMENT->ns = NULL; // NULL means "NO NAMESPACE"(I.E. "UNDEFINED NAMESPACE")
+        }
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Finds namespace declaration that has specific prefix in the scope for given node
+//
+// Prefix "" or NULL are considered the same, meaning "<b>NO PREFIX</b>".
+// If namespace declaration for "no prefix" is searched, then default namespace is returned. 
+//
+// @return Namespace handler, which may be NULL if prefix is not bound.
+//
+// NULL result for "no prefix" means that default namespace is undefined.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngNamespace TXmlEngElement::LookupNamespaceByPrefixL(
+    const TDesC8& aPrefix ) const
+    {
+    // OOM may happen ONLY during a lookup for {"xml","http://www.w3.org/XML/1998/namespace"}
+
+    xmlChar* pref = xmlCharFromDesC8L(aPrefix);
+    // Allow "" instead of NULL
+    if(pref && !*pref)
+        {
+        delete pref;
+        pref = NULL;
+        }
+        
+    xmlNsPtr ns = xmlSearchNs(
+                        LIBXML_ELEMENT->doc,
+                        LIBXML_ELEMENT,
+                        pref
+                );
+    delete pref;
+    // Default namespace undeclarations are never returned  
+    if (ns && ns->href && !*ns->href)
+        ns = NULL;
+    return TXmlEngNamespace(ns);
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Finds namespace declaration that has specific namespace URI
+// in the scope for the given node.
+//
+// @param aUri  Namespace URI, for which namespace declaration is searched
+// @return Handler to the namespace declaration that binds given namespace URI to some prefix 
+//         or NULL if the binding is not active at the scope of this element.
+//
+// NULL value of aUri is equivalent to "" and means "<b>UNDEFINED NAMESPACE</b>". 
+// For such URI  a NULL namespace handle is always returned even if there is
+// namespace undeclaration, which has "" URI (and NULL prefix).
+//
+// <b>Hint:</b><p>
+// Use returned instance of TXmlEngNamespace as aNsDef argument to element's methods
+// that create new element's child elements and attributes. The same handler
+// may be used on more deep descentants of the reference element (and doing
+// this way will generally increase performance of DOM tree construction).<br />
+// <span class="color:red;">However</span>, if namespace bindings are not controlled
+// for element's children and prefix, which is bound to the search namespace, is
+// rebound to some other namespace URI, then reusing namespace may lead to
+// unwanted result.
+//
+// Consider an example:
+// @code
+//     TXmlEngElement root = doc.DocumentElement();
+//     TXmlEngNamespace targetNs = root.AddNamespaceDeclarationL("http://example.com/","ex");
+//     TXmlEngElement el_1 = root.AddNewElementL("outer", targetNs);
+//     TXmlEngElement el_2 = el_1.AddNewElementL("inner"); // element without prefix
+//
+//     // NOTE: prefix "ex" is not bound to "http://example.com/" anymore
+//     el_2.AddNamespaceDeclarationL("http://whatever.com/","ex");
+//     TXmlEngElement el_3 = el_2.AddNewElementL("problem", targetNs);
+//     ...
+// @endcode
+//
+// The sought result was (showing expanded names of elements):
+// @code
+//     --> "root"
+//         --> {"http://example.com/","outer"}
+//         --> "inner"
+//             -->{"http://example.com/","problem"}
+//                 ...
+//             <--
+//         <-- "inner"
+//         <-- {"http://example.com/","outer"}
+//         ...
+//     <-- </root>
+// @endcode
+// and it may look that it has been achieved. Indeed, if namespace of element "problem"
+// was queried, it would have URI "http://example.com/" and prefix "ex".
+// However, if namespace URI was looked up by "problem"'s prefix, it would be
+// "http://whatever.com/". We have created illegal DOM tree.
+//
+// The actual DOM tree in serialized form will be:
+// @code
+//     <root>
+//         <ex:outer xmlns:ex="http://example.com/">
+//            <inner xmlns:ex="http://example.com/">
+//                 <ex:problem>
+//                 ...
+//                 </ex:problem>
+//            </inner>
+//         </ex:outer>
+//        ...
+//     </root>
+// @endcode
+//
+// So, reuse of namespace handlers should be performed with special care.
+//
+// @note
+//     At the moment it is possible to retrieve namespace declaration nodes
+//     whose prefixes were rebound. Be careful when use returned TXmlEngNamespace object
+//     for creation of new elements. In later releases, this method will perform
+//     safe lookup. And so far, it is better to make check that prefix of returned
+//     namespace declaration has not rebound:
+// @code
+//     TXmlEngNamespace ns = element.LookupNamespaceByUri("a_uri");
+//     if (element.LookupNamespaceByPrefix(ns.Prefix()).IsSameNode(ns)){
+//         ... // now it is safe to create new elements by using "ns"
+//         element.AddNewElementL("product",ns);
+//         ...
+//     }
+// @endcode
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngNamespace TXmlEngElement::LookupNamespaceByUriL(
+    const TDesC8& aUri ) const
+    {
+    // OOM may happen ONLY during a lookup for {"xml","http://www.w3.org/XML/1998/namespace"}
+
+    xmlChar* uri = xmlCharFromDesC8L(aUri);
+
+	if(!uri || !*uri)
+		{
+		delete uri;
+		return NULL;
+		}
+	else
+		{
+        TXmlEngNamespace ns = xmlSearchNsByHref(
+                            LIBXML_ELEMENT->doc,
+                            LIBXML_ELEMENT,
+                            uri);	
+        delete uri;	
+		if(LookupNamespaceByPrefixL(ns.Prefix()).IsSameNode(ns))
+			{
+			return ns;
+			}
+		else
+			{
+			return NULL; //the binding is not active at the scope of this element
+			}
+		}
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Retrieves implicitly declared on every XML infoset binding
+// of 'xml' prefix to XML's namespace URI:
+// "http://www.w3.org/XML/1998/namespace"
+//
+// @return Handler to {xml,"http://www.w3.org/XML/1998/namespace"} prefix
+//            binding in the current document
+//
+// The result should be used for creating attributes beloging to the XML namespace
+// (xml:lang, xml:space, xml:id , etc.)
+//
+// DO NOT USE methods LookupNamespaceByUri(TDesC8) and LookupNamespaceByPrefix(TDesC8)
+// (with "http://www.w3.org/XML/1998/namespace" and "xml" arguments) for retrieving
+// namespace node, since in a case of [possible] memory allocation fault
+// NULL result is returned (and breaks your program silently)
+//
+// @note   Normally 'xml' prefix is bound to XML namespace URI in the document
+//         node, BUT if current node is not a part of the document tree yet,
+//         the requested namespace declaration WILL BE ADDED to the current node.
+//         This is the reason why the method may fail in OOM conditions.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngNamespace TXmlEngElement::TheXMLNamespaceL() const
+    {
+    xmlNsPtr ns = xmlSearchNs(
+                        LIBXML_ELEMENT->doc,
+                        LIBXML_ELEMENT,
+                        BAD_CAST "xml");
+    OOM_IF_NULL(ns);
+    return ns;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Performs search of namespace handler in the scope of the element. This method will
+// create new namespace declaration on the element if such namespace is not available.
+//
+// @param aNsUri   Searched namespace
+// @param aPrefix  Prefix to use for <b>new</b> namespace declaration (if it is to be created)
+//
+// @return    TXmlEngNamespace handler that may be used to create new attributes and child elements of
+//             the element. The namespace may be one of those existed previously or was created
+//
+// @see LookupNamespacebyUriL
+// @note
+//     Be sure not to use the result of this method for non-descendants of the element or in situations
+//     when prefix overlapping might occur (read also about general considerations of attributes
+//     and elements creation using namespace handlers)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngNamespace TXmlEngElement::FindOrCreateNsDeclL(
+    const TDesC8& aNsUri,
+    const TDesC8& aPrefix )
+    {
+    TXmlEngNamespace ns = LookupNamespaceByUriL(aNsUri);
+    if (aNsUri.Length() && ns.IsNull())
+        {
+        // Some (not the undefined one) namespace was not declared yet 
+        ns = AddNamespaceDeclarationL(aNsUri, aPrefix);
+        }
+    else
+        {
+        // There is a namespacedeclaration,
+        // check that it is not "shielded" (its prefix is not rebound)
+        if (! LookupNamespaceByPrefixL(ns.Prefix()).IsSameNode(ns))
+            {
+            // it was rebound, so we rebound it again
+            ns = AddNamespaceDeclarationL(aNsUri, aPrefix);
+            }
+        }
+    return ns;
+}
+
+// ---------------------------------------------------------------------------------------------
+// Performs search on the element and its ascendants for any namespace declaration
+// with given URI and create a new namespace declaration with some (unique) prefix
+// if the search was not successful.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngNamespace TXmlEngElement::FindOrCreateNsDeclL(
+    const TDesC8& aNsUri )
+    {
+    _LIT8(KAutoPrefix,"_pr%d");
+    const TInt KMaxPrefLength = 20;
+    TBuf8<KMaxPrefLength> prefix;
+    
+    TXmlEngNamespace ns = LookupNamespaceByUriL(aNsUri);
+    if (ns.NotNull())
+        return ns;
+
+    TBool ready = false;
+    TUint ind = 0;
+    
+    while(!ready)
+        {
+        // generate prefix
+        ++ind;
+        prefix.Format(KAutoPrefix,ind);
+                
+        // check
+        ns = LookupNamespaceByPrefixL(prefix);
+        ready = ns.IsNull();
+        }
+    return AddNamespaceDeclarationL(aNsUri, prefix);
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Adds namespace declaration to the current element, a binding of prefix to namespace URI.
+//
+// If same namespace declaration exists (same prefix and URI), redundant namespace declaration
+// will not be created.
+//
+// Both NULL or "" (empty string) may be used for "UNDEFINED URI" and "NO PREFIX" values of arguments. 
+//
+// @return  A handle to the created (or found, if there is such) namespace declaration node.
+//          If namespace undeclaration is being created, NULL handle is returned -- it can be
+//          used in node-creation methods that take namespace handle as an argument.
+//
+// @note   Undeclaring of default namespace (xmlns="") is supported by
+//         SetNoDefaultNamespace() method
+//
+// @see SetNoDefaulNamespace()
+//
+// @note   By adding namespace declaration that rebinds prefix mapping (or default namespace)
+//         used by nodes lower in the tree, document tree may become
+//         wrongly constructed, because references to namespace declaration are
+//         not updated. However, after serialization the document will have
+//         desired structure.
+//         Use this method with care!
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngNamespace TXmlEngElement::AddNamespaceDeclarationL(
+    const TDesC8& aNsUri,
+    const TDesC8& aPrefix )
+    {
+    if ( !LIBXML_ELEMENT )
+    	{
+    	User::Leave(KXmlEngErrNullNode);
+    	}
+    if(!aNsUri.Length() && aPrefix.Length())
+        {
+        User::Leave(KXmlEngErrWrongUseOfAPI);
+        }
+        
+    // Now we allow NULL instead of ""
+    xmlChar* nsUri = NULL;
+    if(aNsUri.Length())
+        {
+        nsUri = xmlCharFromDesC8L(aNsUri);
+        }
+    else
+        {
+        nsUri = (xmlChar*)new(ELeave) TUint8[1];
+        *(Mem::Copy((TAny*)nsUri, aNsUri.Ptr(), aNsUri.Length())) = 0;
+        }
+        
+    CleanupStack::PushL(nsUri);
+    
+    // Now we allow "" instead of NULL
+    xmlChar* pref = NULL;
+    if(aPrefix.Length())
+        {
+        pref = xmlCharFromDesC8L(aPrefix);
+        }
+    
+    xmlNsPtr ns = xmlNewNs(
+                    LIBXML_ELEMENT,
+                    nsUri,
+                    pref);
+    
+    delete pref;                
+    CleanupStack::PopAndDestroy(nsUri);
+    
+    TEST_OOM_FLAG;
+    if (!ns)
+        {
+        // OOM or Already exists
+        if (HasNsDeclarationForPrefixL(aPrefix))
+            {
+            return FindOrCreateNsDeclL(aNsUri); // unique prefix will be generated
+            }
+        }
+    return TXmlEngNamespace(ns);
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Checks whether a prefix has been bound in this element (not in one of its ascendants)
+//
+// Use this method for preventig prefix-name collision in a element node
+//
+// @return TRUE if there is already namespace declaration that uses aPrefix on this element
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TBool TXmlEngElement::HasNsDeclarationForPrefixL(
+    const TDesC8& aPrefix ) const
+    {
+    xmlChar* prefix;
+    if(!aPrefix.Length())
+        {
+        prefix = NULL;
+        }
+    else
+        {
+        prefix = xmlCharFromDesC8L(aPrefix);
+        }
+    // Convert "" into NULL
+    TXmlEngConstString pref((char*) prefix);
+    xmlNsPtr ns = LIBXML_ELEMENT->nsDef;
+    while (ns)
+        if(pref.Equals((char*)ns->prefix))
+            {
+            delete prefix;
+            return true;
+            }            
+        else
+            ns = ns->next;
+    delete prefix;
+    return false;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Copies the element with its attributes, but not child nodes
+//
+// If context is preserved, then all namespace declarations that are in the element are
+// writen to element's start tag too.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngElement TXmlEngElement::ElementCopyNoChildrenL(
+    TBool aPreserveNsContext ) const
+    {
+    if ( !LIBXML_ELEMENT )
+    	{
+    	User::Leave(KXmlEngErrNullNode);
+    	}
+    //
+    xmlNodePtr ncopy = xmlStaticCopyNode(LIBXML_ELEMENT, NULL, NULL, 0 /* shallow copy */);
+    if (!ncopy) // for a copy of element node, it's not neccessary to check OOM flag
+        {
+        OOM_HAPPENED;
+        }
+    // OOM will be checked in the very end of methods
+    if (LIBXML_ELEMENT->properties)
+        {
+        ncopy->properties = xmlCopyPropList(ncopy, LIBXML_ELEMENT->properties);
+        }
+    if (aPreserveNsContext)
+        {
+        if (LIBXML_ELEMENT->nsDef)
+            {
+            ncopy->nsDef = xmlCopyNamespaceList(LIBXML_ELEMENT->nsDef);
+            }
+        }
+    // DONE: OOM: check OOM flag
+    if (xmlOOMFlag())
+        {
+        xmlFreeNode(ncopy);
+        OOM_HAPPENED;
+        }
+    TXmlEngElement el(ncopy);
+    OwnerDocument().TakeOwnership(el);
+    return el;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Resets element's content: all child nodes are removed
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::RemoveChildren()
+    {
+    //
+    if(!LIBXML_ELEMENT)
+        {
+        return;
+        }
+    xmlFreeNodeList(LIBXML_ELEMENT->children);
+    LIBXML_ELEMENT->children = NULL;
+    LIBXML_ELEMENT->last = NULL;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Resets element's attributes
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::RemoveAttributes()
+    {
+    if(!LIBXML_ELEMENT)
+        {
+        return;
+        }
+    //
+    xmlFreePropList(LIBXML_ELEMENT->properties);
+    LIBXML_ELEMENT->properties = NULL;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Resets all namespace declarations made in the element
+//
+// @note There can be references to these namespace declaration from elsewhere!
+//       Use ReconcileNamespacesL() to fix that.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::RemoveNamespaceDeclarations()
+    {
+    if (!LIBXML_ELEMENT)
+        {
+        return;
+        }
+    xmlNsPtr ns = LIBXML_ELEMENT->nsDef;
+    while(ns)
+        {
+        ResetNs(LIBXML_NODE,ns);
+        ns = ns->next;
+        }
+    
+    xmlFreeNsList(LIBXML_ELEMENT->nsDef);
+    LIBXML_ELEMENT->nsDef = NULL;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Copies attributes from another element
+//
+// It may be a very convenient method for initializing element with a set of predefined attributes.
+//
+// @note
+//     Namespaces of the this element may need to be reconciled if copied attributes
+//     belong to any namespace that is not declared on some ascendant of this node.
+//
+// @see ReconcileNamespacesL()
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::CopyAttributesL(
+    TXmlEngElement aSrc )
+    {
+    if ( !LIBXML_ELEMENT )
+    	{
+    	User::Leave(KXmlEngErrNullNode);
+    	}
+    //
+    if (INTERNAL_NODEPTR(aSrc)->properties)
+        {
+        xmlAttrPtr plist = xmlCopyPropList(LIBXML_ELEMENT, INTERNAL_NODEPTR(aSrc)->properties);
+        OOM_IF_NULL(plist);
+
+        if (LIBXML_ELEMENT->properties)
+            {
+            xmlAttrPtr last = LIBXML_ELEMENT->properties;
+            while (last->next)
+                {
+                last = last->next;
+                }
+            last->next = plist;
+            }
+        else
+            {
+            LIBXML_ELEMENT->properties = plist;
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Copies a list of elements.
+//
+// Elements are appended to the element's children list.
+//
+// @note Namespaces of the this element may need to be reconciled after copy operation
+// @see  ReconcileNamespacesL()
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::CopyChildrenL(
+    TXmlEngElement aSrc )
+    {
+    if ( !LIBXML_ELEMENT )
+    	{
+    	User::Leave(KXmlEngErrNullNode);
+    	}
+    if ( aSrc.IsNull() )
+    	{
+    	User::Leave(KXmlEngErrWrongUseOfAPI);
+    	}
+    if (INTERNAL_NODEPTR(aSrc)->children)
+        {
+        xmlNodePtr plist = xmlStaticCopyNodeList(
+                                INTERNAL_NODEPTR(aSrc)->children,
+                                LIBXML_ELEMENT->doc,
+                                LIBXML_ELEMENT);
+        OOM_IF_NULL(plist);
+        xmlNodePtr last = plist;
+        while (last->next)
+            {
+            last = last->next;
+            }
+        if (LIBXML_ELEMENT->children)
+            {
+            LIBXML_ELEMENT->last->next = plist;
+            plist->prev = LIBXML_ELEMENT->last;
+            }
+        else
+            {
+            LIBXML_ELEMENT->children = plist;
+            }
+        LIBXML_ELEMENT->last = last;
+        }
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Removes attribute with given name and namespace URI(if such exists).
+// Memory allocated for the attribute is freed.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::RemoveChildElementsL(
+    const TDesC8& aLocalName,
+    const TDesC8& aNamespaceUri )
+    {
+    if (!LIBXML_ELEMENT)
+        {
+        return;
+        }
+    //pjj18
+    RXmlEngNodeList<TXmlEngElement> eList;
+    
+    eList.OpenL(
+            LIBXML_ELEMENT->children,
+            TXmlEngNode::EElement,
+            aLocalName,
+            aNamespaceUri);
+
+    TXmlEngElement el;
+    while ((el = eList.Next()).NotNull())
+        el.Remove();
+    eList.Close();
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Renames the element.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::RenameElementL(
+	const TDesC8& aLocalName, 
+	const TDesC8& aNamespaceUri, 
+	const TDesC8& aPrefix)
+	{
+
+        xmlNodePtr element = INTERNAL_NODEPTR(*this);
+
+    	XE_ASSERT_DEBUG( element->type == XML_ELEMENT_NODE );
+
+       	const xmlChar* oldName = element->name;
+       	
+       	XE_ASSERT_ALWAYS(aLocalName.Length());
+       	
+       	element->name = xmlCharFromDesC8L(aLocalName);
+       	
+       	xmlFree((void*)oldName );
+       	
+        if (aNamespaceUri.Length() || aPrefix.Length())
+            {
+            TXmlEngNamespace ns = (*this).FindOrCreateNsDeclL(aNamespaceUri, aPrefix);
+            element->ns = INTERNAL_NSPTR(ns);
+            }
+         
+	}
+
+// ========================================================================================
+
+// DOM Level 3 Core
+
+
+// ---------------------------------------------------------------------------------------------
+// Links attribute into tree
+//
+// The replaced attribute node is not returned and just deleted
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::SetAttributeNodeL(
+    TXmlEngAttr aNewAttr )
+    {
+    AppendChildL(aNewAttr);
+    xmlReconciliateNs(LIBXML_ELEMENT->doc, LIBXML_NODE);
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Returns value of attribute with given name and namespace URI
+//  
+// @param aLocalName       - local name of attribute node
+// @param aNamespaceUri    - namespace URI of attribute
+// ---------------------------------------------------------------------------------------------
+//   
+EXPORT_C TPtrC8 TXmlEngElement::AttributeValueL(
+    const TDesC8& aLocalName,
+    const TDesC8& aNamespaceUri ) const
+    {
+    TXmlEngAttr attr = AttributeNodeL(aLocalName, aNamespaceUri);
+    if( attr.IsNull() )
+    	return KNullDesC8();
+    else
+    	return attr.Value();
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Sets value of attribute; attribute is created if there is no such attribute yet
+//
+// @note
+//     If prefix is not NULL (or ""), then namespace URI may not be empty
+//     see http://www.w3.org/TR/REC-xml-names/#ns-decl (Definition #3)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::SetAttributeL(
+    const TDesC8& aLocalName,
+    const TDesC8& aValue,
+    const TDesC8& aNamespaceUri,
+    const TDesC8& aPrefix )
+    {
+    if ( aLocalName.Length() <= 0 )
+    	{
+    	User::Leave(KXmlEngErrWrongUseOfAPI);
+    	}
+
+    TXmlEngAttr attr = AttributeNodeL(aLocalName, aNamespaceUri);
+    if (attr.NotNull())
+        {
+        attr.SetValueL(aValue);
+        }
+    else
+        {
+        AddNewAttributeL(aLocalName, aValue, aNamespaceUri, aPrefix);
+        }
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Removes attribute with given name and namespace URI(if such exists).
+// Memory allocated for the attribute is freed.
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::RemoveAttributeL(
+    const TDesC8& aLocalName,
+    const TDesC8& aNamespaceUri )
+    {
+    TXmlEngAttr attr = AttributeNodeL(aLocalName, aNamespaceUri);
+    xmlRemoveProp(INTERNAL_ATTRPTR(attr));
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Retrieves attribute node from specific namespace by its name.
+// 
+// @return Attribute node with matching namespace URI and name
+// @note Use "" (empty string) for namespace name, not NULL (for <i>undefined namespace</i>)
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C TXmlEngAttr TXmlEngElement::AttributeNodeL(
+    const TDesC8& aLocalName,
+    const TDesC8& aNamespaceUri ) const
+    {
+    //pjj18
+    RXmlEngNodeList<TXmlEngAttr> attList;
+        
+    attList.OpenL(
+            LIBXML_ELEMENT->properties,
+            TXmlEngNode::EAttribute,
+            aLocalName,
+            aNamespaceUri);
+    TXmlEngAttr attr = attList.Next();
+    attList.Close();
+    return attr;
+    }
+
+// ---------------------------------------------------------------------------------------------
+// Initializes list of child elements with matching name and namespace URI.
+//
+// @note This method does not lists all descedants of the element, only child elements
+// ---------------------------------------------------------------------------------------------
+//
+EXPORT_C void TXmlEngElement::GetElementsByTagNameL(
+    RXmlEngNodeList<TXmlEngElement>& aList,
+    const TDesC8& aLocalName,
+    const TDesC8& aNamespaceUri ) const
+    {
+    aList.OpenL(
+        LIBXML_ELEMENT->children,
+        TXmlEngNode::EElement,
+        aLocalName,
+        aNamespaceUri);
+    }
+