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.