Données d'un XMLElement

Philippe49Philippe49 Membre
septembre 2007 modifié dans Actualités #1
Dans une DTD j'ai cet élément :
<!ELEMENT personne (adresse,telephone*,relation*)>
je veux récupérer la séquence des trois sous-éléments

Y a-t-il une requête XQuery ou un XPath qui fasse cela proprement , en prévoyant tout ce qu'il peut y avoir dans la déclaration de cet élément ?

(j'ai essayé les fils de l'élément,non)
(j'arrive à  obtenir le texte (adresse,telephone*,relation*) mais il n'est pas décomposé, et compte-tenu de la complexité de ce que l'on peut avoir comme déclaration, je préférerais que XQuery ou XPath fasse le boulot)

Merci à  ceux qui savent de la part de ceux qui ne savent pas ....

Réponses

  • AliGatorAliGator Membre, Modérateur
    11:36 modifié #2
    Heu je ne comprend pas exactement la question.

    Tu veux récupérer les éléments venant de ton XML, c'est ça ? (Déjà  j'ai un petit doute, c'est pas le DTD que tu parses, c'est bien le XML, tu nous as donné la déclaration DTD juste pour nous indiquer la forme des données qu'on peut trouver ?)
    Et tu veux récupérer quoi ? Un node-set contenant tout les noeuds mis à  plat ? Leur contenu texte concaténé ?

    En plus tu dit "je veux récupérer la séquence des 3 sous-éléments" mais :
    - Si tu veux parser le XML, il n'y a pas 3 sous-éléments mais de 1 à  une infinité (le "*" voulant dire que les tags <telephone> et <relation> pouvant apparaà®tre, zéro, une ou plusieurs fois) : ça peut être [tt]<personne><adresse /><telephone /><telephone /><telephone /><relation /><relation /></personne>[/tt] par exemple... (j'ai mis des tags vides pour pas surcharger le code juste pour te donner un exemple)

    Si tu veux obtenir le node-set, il suffit de demander en XPath tous les enfants du noeud personne, quels qu'il soient : [tt]//personne/*[/tt] pour obtenir tous les noeuds enfants de toutes les personnes.

    - Si tu veux parser le DTD, je ne suis pas sûr que tu puisses appliquer un XPath si facilement, <!ELEMENT ... > n'étant pas un noeud (tag) classique mais une directive un peu particulière.

    Mais bon comme j'ai pas bien compris exactement ce que tu voulais récupérer et dans quel contexte je ne peux pas t'en dire plus.
  • Philippe49Philippe49 Membre
    11:36 modifié #3
    Je fais une interface graphique pour créer/changer un xml à  partir d'un NSBrowser.
    Dans un NSPopUpButton, je propose à  l'utilisateur les balises disponibles selon la DTD.

    J'ai donc besoin de récupérer dans <!ELEMENT personne (adresse,telephone*,relation*)> une NSArray qui contient {@adresse,@telephone*,@relation*}.

    Je sais déjà  récupérer  (adresse,telephone*,relation*) comme une NSString *, et je pourrais découper con la mano, mais les possibiltés de déclarations sont telles que je préférerais que l'interprétation de cette déclaration soit faite dans les règles de l'art.

    J'ai essayé de lister les fils de cet élément, mais ce n'est pas comme cela que c'est fait.
    Je me tourne donc vers une requête ... cela doit bien exister, reste à  trouver la syntaxe

    Pourtant je bouquine XQuery, mais ...
  • AliGatorAliGator Membre, Modérateur
    11:36 modifié #4
    Je suis pas persuadé que XQuery (que je connais peu voire pas) ni XPath (que je connais déjà  bien mieux) soient aptes à  faire ça, ils sont fait pour parser du XML, pas une DTD. Enfin en tout cas moi je n'ai jamais fait pour ça : donc je dis pas que c'est pas possible, mais je maitrise pas pour ces cas-là .

    Peux-tu nous indiquer comment tu parses jusqu'à  présent ta DTD ? Avec un parseur XML ? En traitant ton DTD comme un fichier texte et récupérant les lignes sous forme de NSString ?

    - Possibilité 1 : utiliser tout bêtement [tt]componentsSeparatedByString:@,[/tt] pour découper ta NSString @adresse,telephone*,relation* en tableau de 3 éléments (éventuellement enlever le "(" et le ")" au début et fin de ta chaà®ne avant, donc
    - Possibilité 2 : Utiliser une RegEx. Le principe est à  peu près le même, donc ça vaut peut-être pas le coup, autant se rabattre sur la possibilité 1
    - Possibilité 3 : Utiliser un XSD (XML Schema Definition) au lieu d'utiliser une DTD : c'est plus flexible et un XSD est lui-même au format XML, donc plus facilement manipulable avec des XPath ou XQuery. C'est limite la solution idéale, encore faut-il avoir le XSD ce qui n'est pas toujours le cas (voir éventuellement s'il existe des trucs pour convertir une DTD en XSD ? Je sais que ça existe, après voir si ça vaut le coup et sous quelle forme)
    - Possibilité 4 si tu arrives à  parser ton DTD avec du XPath (comme je te dis j'ai jamais fait et étant donné que le DTD n'est pas du format XML je sais mm pas si c'est faisable, mais bon je sais pas où tu en es de ton côté), utiliser les extensions de fonctions de XPath comme celles présentes dans le module EXSLT (comme str:split) mais je suis pas sûr que ça soit implémentable dans le contexte de ton programme (et il faut peut-être en plus linker avec libexslt, donc bon ça fait bcp pour pas grand chose). Donc à  mon avis cette solution je laisserai tomber ;)

    Donc la meilleure solution c'est componentsSeparatedByString pour découper ta chaà®ne si tu parses en tant que fichier texte (quitte à  relire la RFC qui concerne le format de la DTD pour voir les diverses possibilités de syntaxe, etc), ou passer par un XSD au lieu d'une DTD.
  • Philippe49Philippe49 Membre
    11:36 modifié #5
    dans 1190298025:

    Peux-tu nous indiquer comment tu parses jusqu'à  présent ta DTD ? Avec un parseur XML ? En traitant ton DTD comme un fichier texte et récupérant les lignes sous forme de NSString ?

    J'utilise les méthodes de NSXML :

    -(NSArray *) childrenAccordingToDTD
    {
    NSXMLDocument * xmlDocument=[self rootDocument];  // le document à  partir du noe“ud
    NSXMLDTD * DTD=[xmlDocument DTD];                      // la DTD
    NSXMLDTDNode * dtdNode=[DTD elementDeclarationForName:[self name]];  // l'élément sur le noe“ud courant
    id value=[dtdNode objectValue];                                // là  j'obtiens la chaà®ne
    return [[value XMLString] componentsSeparatedByString:@,];
    }

    dans 1190298025:

    Donc la meilleure solution c'est componentsSeparatedByString pour découper ta chaà®ne si tu parses en tant que fichier texte (quitte à  relire la RFC qui concerne le format de la DTD pour voir les diverses possibilités de syntaxe, etc), ou passer par un XSD au lieu d'une DTD.


    c'est ce que j'ai fait, et cela marche sur l'exemple simpliste que j'ai fait.

    En fait
    1) je ne sais pas jusqu'où peut aller la complexité dans les déclarations d'éléments,
    2) une solution (si elle marchait, mais elle ne marche pas) comme return [dtdNode children]; serait mieux foutue.

    Ne trouvant pas dans la doc de NSXMLDTDNode & co ce que je veux, je me tourne vers des requêtes que NSXML sait également bien réaliser.

    La requête serait : déterminer sous forme d'un tableau la liste des "objets?" intervenant dans la déclaration de mon élément. 
  • Philippe49Philippe49 Membre
    11:36 modifié #6
    dans 1190298025:

    - Possibilité 4 si tu arrives à  parser ton DTD avec du XPath (comme je te dis j'ai jamais fait et étant donné que le DTD n'est pas du format XML je sais mm pas si c'est faisable, mais bon je sais pas où tu en es de ton côté), utiliser les extensions de fonctions de XPath comme celles présentes dans le module EXSLT (comme str:split) mais je suis pas sûr que ça soit implémentable dans le contexte de ton programme (et il faut peut-être en plus linker avec libexslt, donc bon ça fait bcp pour pas grand chose). Donc à  mon avis cette solution je laisserai tomber ;)


    je peux appliquer sans problème des requêtes sur la DTD.
    Je m'en vais lire ton lien.
  • Philippe49Philippe49 Membre
    11:36 modifié #7
    dans 1190298025:

    - Possibilité 4 si tu arrives à  parser ton DTD avec du XPath (comme je te dis j'ai jamais fait et étant donné que le DTD n'est pas du format XML je sais mm pas si c'est faisable, mais bon je sais pas où tu en es de ton côté), utiliser les extensions de fonctions de XPath comme celles présentes dans le module EXSLT (comme str:split) mais je suis pas sûr que ça soit implémentable dans le contexte de ton programme (et il faut peut-être en plus linker avec libexslt, donc bon ça fait bcp pour pas grand chose). Donc à  mon avis cette solution je laisserai tomber ;)


    oui cela correspond à  componentsSeparatedByStrings mais ça ne prend pas en charge le respect de la norme syntaxique des déclarations de DTD.
  • Philippe49Philippe49 Membre
    11:36 modifié #8
    dans 1190291799:

    (j'ai mis des tags vides pour pas surcharger le code juste pour te donner un exemple)

    ...
    un noeud (tag) classique mais une directive un peu particulière.


    je cherchais justement la traduction de balise : tu dis tag ? markup ? ?
  • AliGatorAliGator Membre, Modérateur
    11:36 modifié #9
    balise -> tag
    noeud -> node
    ensemble de noeud -> node-set

    cf les docs officiells sur le XML & co (W3C) les termes y sont détaillés exactement, ceux à  ne pas confondre, etc. Par exemple un noeud n'est pas forcément un élément de type balise, ça peut être un noeud texte ou une processing-instruction... faut faire gaffe au vocabulaire parfois ;)

    Sinon pour NSXMLDTDNode j'avais pas vu qu'il existait je savais pas qu'il y avait de quoi lire les DTDs directement, tant mieux :) Mais j'ai l'impression qu'il est assez simpliste et ne récupère que les déclarations, sans plus. Du coup je peux pas t'aider plus, je ne sais pas s'il y a un "parseur de DTD" inclus dans Cocoa, ça dépasse mes compétences et ce que j'ai utilisé jusqu'ici  :(
Connectez-vous ou Inscrivez-vous pour répondre.