IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Création XML avec XmlWriter


Sujet :

VB.NET

  1. #1
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut Création XML avec XmlWriter


    J'ai un petit problème dans la génération de la balise principale de mon fichier. Cela doit être dans cet ordre:
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <?xml version="1.0" encoding="UTF-8"?>
    <FctAssain xsi:schemaLocation="http://xml.sandre.eaufrance.fr/scenario/fct_assain/3 
    http://xml.sandre.eaufrance.fr/scenario/fct_assain/3/sandre_sc_fct_assain.xsd" 
    xmlns="http://xml.sandre.eaufrance.fr/scenario/fct_assain/3" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    mais tout ce que j'arrive à faire c'est:
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <?xml version="1.0" encoding="utf-8"?>
    <FctAssain xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xml.sandre.eaufrance.fr/scenario/fct_assain/3 http://xml.sandre.eaufrance.fr/scenario/fct_assain/3/sandre_sc_fct_assain.xsd" 
    xmlns="http://xml.sandre.eaufrance.fr/scenario/fct_assain/3">

    l'ordre indiqué en premier doit être rigoureusement respecté car sinon le programme, non développé par la boîte, ne peut pas le lire le fichier XML

    Je fait comme ceci:
    Code vbnet : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            '* Ajout de l'en-tête XML standard
            _writer.WriteStartDocument()
     
            '* Ajout de l'élément parent et les chemins de schémas
            _writer.WriteStartElement("FctAssain", "http://xml.sandre.eaufrance.fr/scenario/fct_assain/3")
            _writer.WriteAttributeString("xmlns", "xsi", Nothing, "http://www.w3.org/2001/XMLSchema-instance")
            _writer.WriteAttributeString("xsi", "schemaLocation", Nothing, "http://xml.sandre.eaufrance.fr/scenario/fct_assain/3 http://xml.sandre.eaufrance.fr/scenario/fct_assain/3/sandre_sc_fct_assain.xsd")

    Je ne vois pas trop comment mettre les différents chemins dans le bon ordre


    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  2. #2
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Bonjour,

    Ca ne m'étonne pas car l'ordre des attributs n'est pas significatif officiellement.

    Cela étant, que crois que dans VB, on a une fonction XML qui s'appelle WriteEndAttribute, y'a peut être quelque chose à chercher la dedans.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut


    Je ne crois pas en fait, c'est une fonction sans paramètres et qui en plus me génère une exception:
    Le jeton EndAttribute dans l'état Element Start Tag générera un document XML non valide.
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  4. #4
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Re,

    J'ai un peu cherché et je vois pas de solution VB.

    A part écrire le fichier XML comme un fichier texte...
    Et/Ou utiliser un fichier XML comme Template qui posséderaient déjà l'entête formatée...
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  5. #5
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Ca, ça risque d'être un peu plus compliqué car il faudrait que je génère en premier lieu le fichier puis que je change l'en-tête en copiant les données vers un fichier avec l'en-tête dans le bon ordre, si je compte environ 1 minute pour générer un fichier (ils sont gros, environ 15.000 à 20.000 lignes, le plus long ce sont les requêtes de récupération et test de données) sur environ 93 ouvrages (une fois par mois)... je pense que ce n'est pas une pratique intéressante

    Est-ce qu'on peut, avec XmlWriter, écrire dans un fichier qui contient déjà des données ?
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  6. #6
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Re,

    Je ne crois pas... je crois qu'on ne peut écrire et en plus de manière itératif.
    C'est un moyen facile d'écrire un fichier xml, mais ce n'est pas un outil très complet pour manipuler les fichier xml.

    Il reste deux (ou plus?) moyens pour éditer un fichier xml :

    - Xpath, qui va permettre de naviguer entre les noeuds, en ajouter etc... Mais de mon avis, c'est un petit peu laborieux.

    - La sérialization. En créant une classe serializable qui correspond a la structure de votre fichier, vous pourriez ouvrir un fichier facilement (une ligne), lire les données dans le code à travers la classe, et enregistrer le fichier (en une ligne aussi). On peut d'ailleurs définir les nœuds ET les attributs.

    Cependant il faudrait vérifier, pour résoudre votre problème, si la sérialisation conserve l'ordre des attributs de la classe...
    Il faudrait faire un petit test.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  7. #7
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Il faut que j'étudie la façon sérialisation alors. J'avais pris l'option XmlWriter car j'ai pas mal de tests et cas particuliers ainsi que certaines conversions de valeur avant l’enregistrement, cette option permet une certaine souplesse sur la création de fichiers XML. A voir avec la sérialisation comme ça fonctionne.

    Je laisse le thread ouvert au cas où

    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  8. #8
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Si tu as pas mal de cas particuliers et des tests, la sérialization sera d'autant plus utile !

    Car contrairement au XMLWriter, tu n'auras pas besoin de calculer et écrire en même temps et au fur et à mesure...

    Ça ira même beaucoup plus vite, car là tu pourras séparer les étapes: charger, traiter les données, écrire...
    Si en plus le traitement s'applique à beaucoup de fichiers, une petite boucle sur ta procédure, et hop !

    Je suis le thread si tu as besoin d'info.
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  9. #9
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par mactwist69 Voir le message
    Je suis le thread si tu as besoin d'info.
    Heu oui si tu connais un bon tutoriel sur ce sujet ça me sera d'un grand secours
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  10. #10
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    La sérialisation c'est vraiment pas mal mais pas trop conseillé sur les gros fichiers ou le XMLWriter est plus conseillé à cause du nombre de donnée à charger en mémoire, après je ne sais pas si on rentre dans le cas avec ton fichier.

  11. #11
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  12. #12
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Bonjour,
    Citation Envoyé par Franck.H Voir le message
    Heu oui si tu connais un bon tutoriel sur ce sujet ça me sera d'un grand secours
    Il y a ceux de TomLev : La sérialisation XML avec .NET et Aller plus loin avec la sérialisation XML[/QUOTE]

    Sinon il y a des discusions en cours Exemple, suite
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  13. #13
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    Ceux de TomLev sont pas mal mais sont destinés au C#, je trouve qu'il est pas forcément facile de trouver de bon tuto aussi détaillé que ceux de TomLev pour Vb.net

  14. #14
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Sinon comme autre voie "alternative" ; on peut aussi considérer l'utilisation de la classe XDocument et proditer de la possibilité offerte en VB.Net d'utiliser les littéraux xml ; j'ai testé vite fait ce que ça donnait sur le xml initial souhaité et il semblerait que ça fonctionne pas trop mal (à voir si pour le reste du document ça reste aisé d'utilisation)
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  15. #15
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Citation Envoyé par youtpout978 Voir le message
    Ceux de TomLev sont pas mal mais sont destinés au C#, je trouve qu'il est pas forcément facile de trouver de bon tuto aussi détaillé que ceux de TomLev pour Vb.net
    L'important, c'est toutes les explications fournies. (il me semble qu'avec toutes ces explications, ce n'est pas très compliqué de le faire en VB, mais bon, c'est un avis perso.)
    Traductions d'articles :
    La mémoire en .NET - Qu'est-ce qui va où ?
    Architecture DAL de haute performance et DTO ; Version C# : Partie 1,Partie 2,Partie 3 — Version VB.NET : Partie 1,Partie 2,Partie 3
    N'hésitez pas à consulter la FAQ VB.NET, le cours complet de Philippe Lasserre et tous les cours, articles et tutoriels.

  16. #16
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    Citation Envoyé par rv26t Voir le message
    L'important, c'est toutes les explications fournies. (il me semble qu'avec toutes ces explications, ce n'est pas très compliqué de le faire en VB, mais bon, c'est un avis perso.)
    Oui ça aide beaucoup mais quand des fois les noms des méthodes, des classes, des attributs ne sont pas forcements les mêmes tu galères à retrouver les méthodes, classes, attributs correspondants quand ceux-ci existes.

  17. #17
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Citation Envoyé par youtpout978 Voir le message
    Oui ça aide beaucoup mais quand des fois les noms des méthodes, des classes, des attributs ne sont pas forcements les mêmes tu galères à retrouver les méthodes, classes, attributs correspondants quand ceux-ci existes.
    ça reste du .Net avant tout les noms des méthodes, des classes et des attributs n'ont pas vraiment tendance à changer (et dans le cas improbable où ça serait le cas suffit de voir la documentation qui présente souvent des exemples d'utilisation des dits-membres pour chaque langage)
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  18. #18
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Ok

    Citation Envoyé par youtpout978 Voir le message
    Ceux de TomLev sont pas mal mais sont destinés au C#, je trouve qu'il est pas forcément facile de trouver de bon tuto aussi détaillé que ceux de TomLev pour Vb.net
    Je n'ai aucun problème à retranscrire du code C# en VB.Net, je l'ai déjà fait à plusieurs reprises

    Citation Envoyé par Sehnsucht Voir le message
    ça reste du .Net avant tout les noms des méthodes, des classes et des attributs n'ont pas vraiment tendance à changer (et dans le cas improbable où ça serait le cas suffit de voir la documentation qui présente souvent des exemples d'utilisation des dits-membres pour chaque langage)
    Oui tout à fait, normalement les noms ne changent pas car cela reste les mêmes bibliothèques.


    Pour le moment et après de nouveaux tests et discussions avec l'aimable dame de l'agence qui récupère nos données, pour le moment les fichiers générés arrivent à être importé sans problème, on ne sais pas pourquoi avant il y avait le problème de l'en-tête. Je vais tout de même voir ce que permet la sérialisation et ce qu'on peut y gagner en terme de temps de développement, de souplesse ou autres points. La plupart des fichiers ne seront guère plus gros que celui mis en pièce jointe.
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  19. #19
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    Citation Envoyé par Franck.H Voir le message
    Ok


    Je n'ai aucun problème à retranscrire du code C# en VB.Net, je l'ai déjà fait à plusieurs reprises
    Moi j'ai du mal à faire le contraire à chaque fois que je lis du Vb ça me donne le tournis, heureusement qu'il y a des outils comme Telerik converter.

  20. #20
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Citation Envoyé par youtpout978 Voir le message
    Moi j'ai du mal à faire le contraire à chaque fois que je lis du Vb ça me donne le tournis, heureusement qu'il y a des outils comme Telerik converter.
    Je trouve que c'est un bon exercice
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

Discussions similaires

  1. [DOM] création de fichier XML avec PHP
    Par cortex007 dans le forum Bibliothèques et frameworks
    Réponses: 7
    Dernier message: 09/12/2007, 11h31
  2. [DOM] Création d'un noeud xml avec childNode
    Par starr dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 22/03/2007, 11h18
  3. [XSLT] création d'un RSS : diffusion des liens xml avec xslt
    Par elhout dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 21/03/2007, 16h23
  4. [JDOM] Création d'un fichier xml avec jdom
    Par fabricew59 dans le forum Format d'échange (XML, JSON...)
    Réponses: 4
    Dernier message: 09/08/2006, 11h17
  5. [DOM XML][XSLT] Création d'un document XML avec PHP
    Par ToxiZz dans le forum Bibliothèques et frameworks
    Réponses: 21
    Dernier message: 16/01/2006, 17h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo