Hi Migad,

At 16.35 19/06/2006 +0200, Migad Negib wrote:

Sorry, I'll use the mailing list for further mails...

I am using the version 2.7.0 of xerces for C++ (but I got the same problem on the Java version 7.2.1)

I don't see in your code the exact place where this happens, but the issue is that you are somewhere removing the xmlns:PRE namespace declaration that is attached to the root node; once you remove that, the serialization code will make it appear again attached to the D element (because it has been created as namespace-aware element and it carries the namespace URI). But an attribute like xsi:type (or any other attribute that has a QName value) is not inspected, and it's your task to ensure that the proper namespace bindings are in place.

Hope this helps,
Alberto


Here is the code for parsing:

--------------------------------------------------------------------------------

/**

* Embedded Parse method

* @param[in] entityPath a string that contains the path to the file to parse

* @param[in] schemaPath a string that contains the path to the schema to use for validation

* @return the root element

* @throw std::exception if Document is NULL, xerces exception are not catched...

*/

XERCES_CPP_NAMESPACE::DOMElement&

CDataParser::parse(const std::wstring& entityPath, const std::wstring& schemaPath)

{

// First releasing the parser data

this->releaseParsedData();

// Then setting few features

_parser->setFeature(XMLUni::fgXercesDOMHasPSVIInfo,true);

_parser->loadGrammar(schemaPath.c_str(), Grammar::SchemaGrammarType, true);

_parser->setValidationScheme(XERCES_CPP_NAMESPACE::DOMBuilderImpl::Val_Always);

_parser->setDoNamespaces(true);

_parser->setDoSchema(true);

_parser->setFeature(XMLUni::fgXercesGenerateSyntheticAnnotations,true);

// Parsing a file

_parser->parseURI(entityPath.c_str());

if ( _parser->getDocument() == NULL)

{

TRACE_DEF

TRACE_TRACE_DEBUG("CDataParser::parse : Unparsed File : %1% with grammar %2%", %entityPath %schemaPath)

throw (std::exception("CDataParser::parse : Unparsed File !"));

}

_pRootElt = _parser->getDocument()->getDocumentElement();

if(_pRootElt == NULL)

{

TRACE_DEF

TRACE_TRACE_DEBUG("CDataParser::parse : File : %1% with grammar %2%, No root element", %entityPath %schemaPath)

throw (std::exception("this->getDocument()->getDocumentElement() == NULL"));

}

return *_pRootElt;

}

--------------------------------------------------------------------------------

This methode is called to build a CData which a kind of DOM encapsulation :

CDataParser dp;

XERCES_CPP_NAMESPACE::DOMElement& root = dp.parse("myXMLFile","myXSDFile");

CData rootData(root);

We want then, to serialize one of the "rootData" descendant (Let's call it descData)

std::wstring xmlStr;

descData.toXML(xmlStr,true);



Here is the serialization code :

--------------------------------------------------------------------------------

/**

* Adds attributes node

*

* @param[in] ele a DOMElement where attributes are added

* @throw xerces exceptions

*/

void

CData::addAttrNodes(xercesc::DOMElement* ele) const

{

xercesc::DOMNamedNodeMap* dom=_dom->getAttributes();

if (!dom) return;

for (XMLSize_t i = 0; i<dom->getLength();++i)

{

xercesc::DOMNode* attr = dom->item(i);

ele->setAttributeNS(attr->getNamespaceURI(),attr->getNodeName(),attr->getNodeValue());

}

}

/**

* CData reccursive subtree building method

*

* @brief this method reccursively attaches nodes to build a DOM subtree from a CData subtree

* @param[in] owner document node

* @param[in] parent node

* @param[in] withGrammar a boolean that says whether grammar should be used to validate

* instanciated nodes.

* @throw xerces exceptions

*/

void

CData::toNode(xercesc::DOMDocument* owner, xercesc::DOMNode* parent, bool withGrammar) const

{

if (!parent)

{

return;

}

if (!owner)

{

return;

}

if (!_isEmpty)

{

const XMLCh* nm = getName();

const XMLCh* ns =_dom->getNamespaceURI();

xercesc::DOMElement* currentNode = owner->createElementNS(ns,nm);

addAttrNodes(currentNode);

if (isValue())

{

const XMLCh* t = getValue();

currentNode->setTextContent(t);

}

CDataList* res = dynamic_cast<CDataList*> (this->instanciateDataChildren(withGrammar));

if (NULL!=res)

{

for(unsigned int i = 0; i<res->getChildrenLength();++i)

{

const IData* child=res->getChild(i);

const IDOMAble* childDOMAble=dynamic_cast<const IDOMAble*>(child);

if (childDOMAble!=NULL)

{

childDOMAble->toNode(owner,currentNode,withGrammar);

}

else //unknown method to get the node trying to convert into text

{

std::wstring text;

child->toXML(text);

currentNode->setTextContent(text.c_str());

}

}

delete res;

}

parent->appendChild(currentNode);

}

}

--------------------------------------------------------------------------------

/**

* CData serialization method

*

* @brief this method reccursively serialize CData subtree

* @param[in] owner document node

* @param[in] parent node

* @throw xerces exceptions

*/

void

CData::toXML(std::wstring& text, bool withGrammar) const

{

if (!_isEmpty)

{

xercesc::DOMImplementation* impl = tools::xml::api::CXercesManager::getDomImplementation(tools::xml::api::VTypeOfDomImplCore);

xercesc::DOMDocument *dc = impl->createDocument();

xercesc::DOMWriter *serializer = ((xercesc::DOMImplementationLS*)impl)->createDOMWriter();

// Settings...

if (serializer->canSetFeature(xercesc::XMLUni::fgDOMWRTSplitCdataSections, false))

serializer->setFeature(xercesc::XMLUni::fgDOMWRTSplitCdataSections, false);

if (serializer->canSetFeature(xercesc::XMLUni::fgDOMWRTDiscardDefaultContent, false))

serializer->setFeature(xercesc::XMLUni::fgDOMWRTDiscardDefaultContent, false);

if (serializer->canSetFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, false))

serializer->setFeature(xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, false);

if (serializer->canSetFeature(xercesc::XMLUni::fgDOMWRTBOM, false))

serializer->setFeature(xercesc::XMLUni::fgDOMWRTBOM, false);

serializer->setEncoding(L"UTF-8");

dc->setEncoding(L"UTF-8");

// Building a subtree

this->toNode(dc,dc, true);

// Writting node

xercesc::MemBufFormatTarget myTarget;

serializer->writeNode(&myTarget,*dc);

std::string mbs ;

mbs.assign( (const char*)myTarget.getRawBuffer(), myTarget.getLen() ) ;

text += tools::xml::api::CXStr(mbs) ;

serializer->release();

dc->release();

}

}

---------------------------------------------------------------------------------



It's not really easy to read, that is the reason why I thought it would be a better way to talk about the "theory".

When I call xercesc::DOMWriter::writeNode method, xerces adds the namespace definition when it encounters a node that uses it.

When a prefix is used within attribute string value, it seems to me that xerces doesn't see it, even if

this attribute stands for a definition of an abstract type.

Am I right ?



Migad





-----Message d'origine-----

De : Alberto Massari [mailto:[EMAIL PROTECTED]

Envoyé : lundi 19 juin 2006 14:23

À : Migad Negib

Cc : <mailto:[email protected]>[email protected]

Objet : Re: prefix in xsi:type attribute



Hi Migad,

in general, it's better to use the <mailto:[email protected]>[email protected] mailing

list, so that your question reaches a wider audience and is also a

way to learn for others.

Coming to your question, you don't say which version of Xerces you

are using, and how you are parsing and serializing the XML stream.

Alberto

At 14.08 19/06/2006 +0200, Migad Negib wrote:

>Hello Alberto Massari,

>

>I'm sorry to disturb you.

>

>I'm using xsi:types in a schema I use while validating xml stream.

>

>I will try to give a simple example that illustrate my problem.

>

>Here is an XML stream:

>

><?xml version="1.0" encoding="UTF-8" standalone="no" ?>

> <root xmlns="rootNamespace:1.0" xmlns:PRE="urn:this:prefix">

> <A>

> <B>

> <C

> xmlns:xsi="<<http://www.w3.org/2001/XMLSchema-instance>http://www.w3.org/2001/XMLSchema-instance>http://www.w3.org/2001/XMLSchema-instance

> " xsi:type="PRE:AbstractCType1">

> <PRE:D>value</PRE:D>

> </C>

> </B>

> </A>

></root>

>Then after parsing and serialization I obtain :

>

><?xml version="1.0" encoding="UTF-8" standalone="no" ?>

> <root xmlns="rootNamespace:1.0">

> <A>

> <B>

> <C

> xmlns:xsi="<<http://www.w3.org/2001/XMLSchema-instance>http://www.w3.org/2001/XMLSchema-instance>http://www.w3.org/2001/XMLSchema-instance

> " xsi:type="PRE:AbstractCType1">

> <D xmlns="urn:this:prefix">value</D>

> </C>

> </B>

> </A>

></root>

>

>Then when I try to parse this result, Xerces tells me (while

>processing the attribute xsi:type, I suppose)

>

>that the prefix PRE is not defined which is true !

>

>I think the definition is forgotten because during the

>serialization, XERCES does not process the attribute node value .

>

>Is there a way to overcome this issue?

>

>I would be very pleased if you can give me a clue.

>

>Thank you.

>

>Migad.

Reply via email to