Forum Programmation.c++ XML, Xerces C++ & XPath

Posté par .
Tags : aucun
0
22
nov.
2004
Bonjour...

Est ce que l'un de vous est un bon en Xerces C++ ???

Moi je botte en touche...

Normalement XPath doit permettre de formuler des expressions de recherche de Node dans un document XML.

Exemple dans le fichier XML suivant...

<maBalisePrincipale>

<mesBalisesText>Toto</mesBalise_Niveau3>
<mesBalisesText>Titi</mesBalise_Niveau3>
<mesBalisesText>Tutu</mesBalise_Niveau3>

</maBalisePrincipale>

L'expression XPath "maBalisePrincipale/maBalise/mesBalisesText[2]"
permet de récupérer le Node, permettant de récupérer le texte Tutu...

Mon problème c'est comment utiliser ce truc sous Xerces C++. J'utilise pour ce faire la dernière version 2.6... et dans l'aide en ligne je vois que l'implémentation du DOM Level 3, n'est que partiel... et visiblement le "partiel" de cette implémentation à l'air de concerner XPath... et là ça m'inquiète...

D'après w3schools on devrait pouvoir faire dans le meilleur des mondes xmlDoc.selectNodes("/catalog/cd")... mais Xerces C++ ne me propose pas cette méthode... même dans les objets XPath...

Comment faire ???
  • # La galère

    Posté par . Évalué à 2.

    Ben tu tombes bien, parce que j'ai eu le même problème y'a quelque temps. J'ai du migrer la configuration d'un serveur depuis WinRegistry + INI pour passer à du XML. C'est tout naturellement que j'ai commencé par MSXML (pour l'abandonner rapidement ;-)) pour en arriver à Xerces.

    Je me souviens avoir eu d'énormes problèmes pour trouver des exemples et les appliquer à mon cas de figure. La version Java est comme d'habitude bien plus simple à gérer.

    Bref, faut que je retrouve tout ça dans mes archives...
    • [^] # Re: La galère

      Posté par . Évalué à 2.

      Bon, j'ai retrouvé, mais c'est un peu le foutoir. J'espère que ça te sera quand même utile. J'ai utilisé Xerces et Xalan pour faire des requêtes XPath.
      
      Voici à peu près à quoi ressemble mon header file:
      ----------------------------------------------------
      
      // xercesc & xalanc
      #include <xercesc/dom/DOMDocument.hpp>
      #include <xercesc/util/PlatformUtils.hpp>
      #include <xalanc/XalanDOM/XalanDocument.hpp>
      #include <xalanc/XalanSourceTree/XalanSourceTreeDOMSupport.hpp>
      #include <xalanc/XalanSourceTree/XalanSourceTreeParserLiaison.hpp>
      #include <xalanc/XPath/XObjectFactoryDefault.hpp>
      
      typedef vector ResultVector;
      
      
      class XPathWrapper
      {
      public:
      	class ConstParameters{
      	public:
      		const char* fXml;
      
      		ConstParameters( const char* AnXml ) : fXml( AnXml ) {}
      	};
      
      private:
      	// useful for creating new documents
      	XalanSourceTreeDOMSupport	 support;
      	XalanSourceTreeParserLiaison liaison;
      
      protected:
      	XalanDocument*	doc;		// "default" xml file
      
      protected:
      	XPathWrapper();
      
      public:
      	inline bool		IsValid() { return doc != NULL; }
      	bool			Execute(const char* xpath_query, ResultVector& result );
      
      	XalanDocument*	GetDocument() { return doc; }
      
      	// Xerces initialization
      	XPathWrapper( const ConstParameters& c );
      
      	// Xerces termination
      	virtual ~XPathWrapper();
      
      };
      
      
      
      
      
      
      
      
      
      Et mon fichier source:
      ----------------------------------------------------
      
      
      
      // xercesc & xalanc
      #include <xercesc/framework/MemBufInputSource.hpp>
      #include <xercesc/parsers/AbstractDOMParser.hpp>
      #include <xercesc/dom/DOMImplementation.hpp>
      #include <xercesc/dom/DOMImplementationLS.hpp>
      #include <xercesc/dom/DOMImplementationRegistry.hpp>
      #include <xercesc/dom/DOMElement.hpp>
      #include <xercesc/dom/DOMBuilder.hpp>
      #include <xercesc/dom/DOMException.hpp>
      #include <xercesc/dom/DOMNodeList.hpp>
      #include <xercesc/dom/DOMError.hpp>
      #include <xercesc/dom/DOMLocator.hpp>
      #include <xercesc/dom/DOMNamedNodeMap.hpp>
      #include <xercesc/dom/DOMAttr.hpp>
      
      #include <xalanc/Include/STLHelper.hpp>
      #include <xalanc/XalanDOM/XalanElement.hpp>
      #include <xalanc/PlatformSupport/DirectoryEnumerator.hpp>
      #include <xalanc/PlatformSupport/DOMStringHelper.hpp>
      #include <xalanc/DOMSupport/DOMServices.hpp>
      #include <xalanc/XPath/XObjectFactoryDefault.hpp>
      #include <xalanc/XPath/XPath.hpp>
      #include <xalanc/XPath/XPathConstructionContextDefault.hpp>
      #include <xalanc/XPath/XPathEnvSupportDefault.hpp>
      #include <xalanc/XPath/XPathExecutionContextDefault.hpp>
      #include <xalanc/XPath/XPathInit.hpp>
      #include <xalanc/XPath/XPathProcessorImpl.hpp>
      #include <xalanc/XPath/XPathFactoryDefault.hpp>
      #include <xalanc/XPath/ElementPrefixResolverProxy.hpp>
      #include <xalanc/XalanDOM/XalanNamedNodeMap.hpp>
      #include <xalanc/XalanSourceTree/XalanSourceTreeDOMSupport.hpp>
      
      
      XPathWrapper::XPathWrapper( const ConstParameters& c ) : support(), liaison(support) 
      {
      	try
      	{
      		XMLPlatformUtils::Initialize();
      		support.setParserLiaison(&liaison);
      		if( !( doc = CreateDocument( c.fXml, c.fIsPath ) ) )
      			Logger::Put( Level::Error, "XPathWrapper> Initialization failed!" );
      	}
      	catch(const XMLException&)
      	{
      		Logger::Put(Level::Error, "XMLPlatformUtils::Initialize() failed!");
      		throw;
      	}
      }
      
      XPathWrapper::~XPathWrapper()
      {	
      	XMLPlatformUtils::Terminate();
      }	
      
      
      /**
       * Executes a XPath query, given a parsed document
       * Returns ALL results as string vector
       */
      bool XPathWrapper::Execute( const char* xpath_query, ResultVector& result ) 
      {
      	try
      	{
      		XObjectPtr xObj;
      		if( !Execute( xpath_query, &xObj ) )
      			return false;
      
      		switch ( xObj->getType() )
      		{
      			case XObject::eTypeNodeSet:
      			{
      				const NodeRefListBase& nodeset = xObj->nodeset();
      				int len = nodeset.getLength();
      
      				for ( int i = 0; i < len; i++ )
      				{
      					XalanNode* const	node = nodeset.item( i );
      					XalanDOMString		str;
      
      					const int type = node->getNodeType();
      
      					switch( node->getNodeType() ) {
      						case XalanNode::COMMENT_NODE:
      						case XalanNode::PROCESSING_INSTRUCTION_NODE:
      							continue;
      						case XalanNode::ELEMENT_NODE:
      							str = node->getNodeName();
      							break;
      						default:
      							DOMServices::getNodeData( *node, str );
      					}	
      					result.push_back( ConvertXalanString( str ) );
      				}
      
      				break;
      			}
      
      			default:
      			{
      				XalanDOMString str = xObj->str();
      				result.push_back( ConvertXalanString( str ) );
      				break;
      			}
      		}	
      	}
      	catch(...)
      	{
      		Logger::Put( Level::Error, "XPathWrapper> (Execute2) Exception detected during execution!" );
      		return false;
      	}
      	return true;
      }
      
      
      Voilà. Le code est probablement incomplet (c'est juste un copier-coller d'une partie du code). Il faut encore configurer ton environnement pour les librairies et headers de Xalan et Xerces. Mais tu devrais pouvoir assez rapidement compléter ce qui te manque...
      • [^] # Re: La galère

        Posté par (page perso) . Évalué à 2.

        arf ! j'en connais un qui va être content ! :-))
      • [^] # Et sans Xalan ???

        Posté par . Évalué à 1.

        Pas mal... mais je pensais faire sans Xalan...
        Non pas que j'aime pas Xalan... mais je pensais que Xerces suffirait...
        J'ai déjà un peu regardé Xalan, et j'aimerais me contenter de Xerces...

        Comment utiliser XPath avec Xerces seulement... vu que les objets ont l'air d'exister...

        En plus je comprends pas très bien l'étroit rapport entre Xalan et Xerces... Ces deux libs sont développés par les mêmes personnes... d'ailleurs Xalan à l'air d'utiliser Xerces... alors pourquoi l'implémentation de Xerces sur le DOM Level 3 est incomplète, alors que cela n'a pas l'air d'être le cas sur Xalan ???

        En tout cas merci...
        • [^] # Re: Et sans Xalan ???

          Posté par . Évalué à 1.

          Alors là, je peux pas trop de répondre...
          Effectivement Xalan utilise Xerces mais j'ai pas essayé les requêtes XPath seulement avec Xerces (sans Xalan).

          Je sais même pas si c'est possible.
          • [^] # Re: Et sans Xalan ???

            Posté par . Évalué à 1.

            Bon ben après plusieurs essais... et beaucoup de recherche notamment autour de la méthode
            void * DOMXPathEvaluator::evaluate (const XMLCh *expression, DOMNode *contextNode, const DOMXPathNSResolver *resolver, unsigned short type, void *result)
            et surtout de son implementation dans la version 2.6 on constate ceci :
            {
            throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager());
            }

            ce qui sent bon ce que je préssentais tout à l'heure... XPath est partiellement implémenté... euh pardon n'est pas du tout implémenté.

            Mon salut sera peut-être dans Xalan... mais pourquoi ce truc est plus complet que xerces.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.