Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Pages: 1
Bonjour,
Pour la création d'un fichier XML, j'ai une 1ere partie entete avec des paramètres, et j'ai donc utilisé PBDOM.
La première instruction est
PBDOM_DOCUMENT_SHIP.NewDocument ("", "", "cXML", "", "http://.......fill.dtd")
et ensuite j'utilise les fonction AddContent pour ajouter les 1ers elements
Mais lors de la sauvegarde du fichier, la 1ere ligne <?xml version="1.0" encoding="UTF-8"?> n'apparait pas dans le fichier.
J'ai bien vu dans l'aide PBDOM_PROCESSINGINSTRUCTION qui devrait me permettre d'ajouter le PI dans le fichier, mais je n'y arrive pas.
Quelqu'un a-t-il utilisé PBDOM pour ajouter le Process Instruction dans un fichier xml ? Merci d'avance,
Hors ligne
PB et l'UTF-8, c'est plutôt chaotique
Moi j'ai le code suivant en stock pour générer un fichier xml en utf-16 cohérent et compréhensible par un autre programme.
Je ne me rappelle plus si j'ai pu créer un fichier en utf-8 (ça date d'il y a 3 ans) mais sans la processing instruction on a de l'utf-16 qui ne s'annonce pas et le fichier merdoie à la relecture par un tiers (ici du java).
Bon courage
PBDOM_Document xml_doc PBDOM_ProcessingInstruction xml_process PBDOM_Element xml_root //... try xml_doc = create PBDOM_Document xml_doc.newdocument(root_name) //utilise une processing instruction : pour ajouter le <?xml version="1.0" encoding="utf-16le"?> au début //sinon le document xml ne comporte pas de déclaration xml_process = create PBDOM_ProcessingInstruction xml_process.setname("xml") xml_process.setvalue("version", "1.0") xml_process.setvalue("encoding", "utf-16le") //utf16-le nécessaire pour être cohérent //car le fichier est écrit dans cet encodage (à cause de windows ?) xml_doc.addcontent(xml_process) destroy xml_process xml_root = xml_doc.getrootelement() //xml_root.setattribute(...) //xml_root.setattribute(...) //xml_root.addcontent(...) //etc if lb_ret then xml_doc.savedocument(as_filename) end if destroy xml_root destroy xml_doc return lb_ret CATCH ( PBDOM_Exception pbde ) MessageBox( "PBDOM Exception", pbde.getMessage() ) CATCH ( PBXRuntimeError re ) MessageBox( "PBNI Exception", re.getMessage() ) end try
Hors ligne
Yes, c'est exactement ce qu'il me fallait,et en plus ça marche
Merci, Merci
Hors ligne
De rien
Pour ma culture personnelle : tu as pu modifier pour obtenir de l'utf-8, ou ça permet juste de faire tomber le truc en marche en rendant l'utf-16 correct ?
Hors ligne
seki a écrit:
De rien
Pour ma culture personnelle : tu as pu modifier pour obtenir de l'utf-8, ou ça permet juste de faire tomber le truc en marche en rendant l'utf-16 correct ?
Bonjour,
En fait, j'ai besoin de générer un fichier xml dont le début du fichier doit respecter cette syntaxe, je dois donc apporter cette précision, mais cela ne change rien à mon fichier, cela permettra simplement l'interprétation du fichier par notre fournisseur.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cXML SYSTEM "http://xxxx/Fulfill.dtd"> <cXML payloadID="xxx" timestamp="xxx" version="1.2.021" xml:lang="en-FR">
Le fichier comportant une grande partie d'entete, que je devrais récupérer pour d'autres fichiers, je l'ai géré avec le pbdom.
//creation du document xml PBDOM_DOCUMENT_SHIP.NewDocument ("", "", "cXML", "", "http://xml.cxml.org/schemas/cXML/1.2.021/Fulfill.dtd") //ajout du Processing instruction pbdom_PI = create PBDOM_ProcessingInstruction pbdom_PI.setname("xml") pbdom_PI.setvalue("version", "1.0") pbdom_PI.setvalue("encoding", "UTF-8") PBDOM_DOCUMENT_SHIP.addcontent(pbdom_PI) //positionnement de la root et de ses attributs PBDOM_DOCUMENT_SHIP.GetRootElement().SetAttribute("payloadID","xxx") PBDOM_DOCUMENT_SHIP.GetRootElement().SetAttribute("timestamp","xxx") PBDOM_DOCUMENT_SHIP.GetRootElement().SetAttribute("version","1.2.021") PBDOM_DOCUMENT_SHIP.GetRootElement().SetAttribute("lang", "en-FR")
Ce qui me donne
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cXML SYSTEM "http://bbb/Fulfill.dtd"> <cXML lang="en-FR" xmlns="" version="1.2.021" payloadID="xxx" timestamp="xxx">
Par contre, je n'arrive pas à positionner le paramètre :
xml:lang
car si je mets
PBDOM_DOCUMENT_SHIP.GetRootElement().SetAttribute("xml:lang", "en-FR")
J'ai l'erreur
pbdom_element::SetAttribute(string strName, string strValue)
Name : "xml:lang" contains a colon.
Et je n'arrive pas à supprimer le paramètre xmlns=""
Aurais-tu de bonnes idées pour m'aider à résoudre ces 2 nouveaux problèmes ?
Merci d'avance,
Hors ligne
wazou1812 a écrit:
Ce qui me donne
Code:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cXML SYSTEM "http://bbb/Fulfill.dtd"> <cXML lang="en-FR" xmlns="" version="1.2.021" payloadID="xxx" timestamp="xxx">Par contre, je n'arrive pas à positionner le paramètre :
xml:lang
car si je metsCode: pb
PBDOM_DOCUMENT_SHIP.GetRootElement().SetAttribute("xml:lang", "en-FR")
J'ai l'erreur
pbdom_element::SetAttribute(string strName, string strValue)
Name : "xml:lang" contains a colon.
la partie qui précède les deux points (colon) dans un nom de tag ou d'attribut c'est le namespace. Ça fonctionnera peut-être mieux avec la version surchargée de SetAttribute qui prend le namespace en paramètre séparément :
SetAttribute(string strName, string strValue, string strNamespacePrefix, string strNamespaceUri, boolean bVerifyNamespace)
Sans doute un truc du genre (non testé, à voir pour la pertinence des 2 derniers arguments) :
PBDOM_DOCUMENT_SHIP.GetRootElement().SetAttribute("lang", "en-FR", "xml", "", false)
Le booléen à la fin permet de valider le bien fondé de cet attribut, pour l'avant dernier paramètre (strNamespaceUri), ça dépend du namespace de ton document, si tu en utilises un.
Edit n°2 : en relisant tout ça d'un peu plus haut je remarque que tu essaies de spécifier les attributs lang et xml:lang. Tu as vraiment besoin de spécifier les 2 versions ? Moi je garderais lang pour la déclaration (et xml:lang si nécessaire pour un noeud particulier si besoin)
wazou1812 a écrit:
Et je n'arrive pas à supprimer le paramètre xmlns=""
Aurais-tu de bonnes idées pour m'aider à résoudre ces 2 nouveaux problèmes ?
Des idées, j'en ai plein, mais bonnes c'est à voir
Le xmlns="" provient du 2ème paramètre de ton NewDocument(), c'est le namespace du noeud racine selon la doc :
The namespace prefix of the root element to be contained in the DOM document. This can be an empty string.
Je pense que spécifier cet attribut à vide ne doit poser de problème pour le parsing du document (càd ce n'est pas faux).
Ça aide ?
PS (edit) : au fait pour ton utf-8, tu es sûre qu'en mettant la processing instruction à "utf-8" PB te fabrique un fichier vraiment en utf-8, ou un fichier en utf-16 dont l'entête prétend qu'il est en utf-8 ?
Je veux dire en regardant le fichier de près (avec un éditeur hexa), tu vois (vrai-faux utf-8, en fait de l'utf-16)
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 00000000 FF FE 3C 00 3F 00 78 00 6D 00 6C 00 20 00 76 00 65 00 72 00 73 00 69 00 6F 00 6E 00 3D 00 22 00 ÿþ<.?.x.m.l. .v.e.r.s.i.o.n.=.". 00000020 31 00 2E 00 30 00 22 00 20 00 65 00 6E 00 63 00 6F 00 64 00 69 00 6E 00 67 00 3D 00 22 00 75 00 1...0.". .e.n.c.o.d.i.n.g.=.".u. 00000040 74 00 66 00 2D 00 38 00 22 00 3F 00 3E 00 0A 00 3C 00 72 00 65 00 70 00 6F 00 72 00 74 00 73 00 t.f.-.8.".?.>...<.r.e.p.o.r.t.s.
ou vraiment (utf-8)
Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 00000000 EF BB BF 3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E 3D 22 31 2E 30 22 20 65 6E 63 6F 64 69 6E 67 3D <?xml version="1.0" encoding= 00000020 22 75 74 66 2D 38 22 3F 3E 0D 0A 3C 72 65 70 6F 72 74 73 20 43 3D 22 4C 22 20 44 3D 22 4E 22 20 "utf-8"?>..<reports C="L" D="N"
Dernière modification par seki (28-09-2011 10:28:05)
Hors ligne
Bonjour,
Pour utf-8 , effectivement c'est du vrai-faux utf-8, mais je ne pense pas que cela soit genant pour l'exploitation de mon fichier.
Pour
PBDOM_DOCUMENT_SHIP.GetRootElement().SetAttribute("lang", "en-FR", "xml", "", false)
C'est ce qu'il faut, sauf qu'il n'accepte pas le paramètre xml, j'ai l'erreur
Function Name : pbdom_element::SetAttribute(string strName, string strValue, string strNamespacePrefix, string strNamespaceUri, boolean bVerifyNamespace) Input NAMESPACE PREFIX is invalid.
Car, si je mets "toto" à la place de "xml", cela fonctionne bien, mais le paramètre doit être facultatif, puisqu'en validant le fichier par w3c sans ce paramètre, je n'ai pas d'erreur, donc pour le moment, j'abandonne.
Par contre, le paramètre xmlns ne peut être vide en validation w3c, même si effectivement dans PB cela ne pose pas de problème, ci dessous le message en validation w3c
Line 3, Column 13: there is no attribute "xmlns" <cXML xmlns="" version="1.2.021" payloadID="131042...✉ You have used the attribute named above in your document, but the document type you are using does not support that attribute for this element. This error is often caused by incorrect use of the "Strict" document type with a document that uses frames (e.g. you must use the "Transitional" document type to get the "target" attribute), or by using vendor proprietary extensions such as "marginheight" (this is usually fixed by using CSS to achieve the desired effect instead). This error may also result if the element itself is not supported in the document type you are using, as an undefined element will have no supported attributes; in this case, see the element-undefined error message for further information.
J'ai donc essayé de supprimer ce paramètre, mais pour le moment, je n'y arrive pas.
J'ai essayé d'accéder à cette ligne, afin de la supprimer, et de la recréer avec les bons paramètres, mais toujours en vain,
Peut être une idée ?
Merci d'avance,
Hors ligne
wazou1812 a écrit:
Pour utf-8 , effectivement c'est du vrai-faux utf-8, mais je ne pense pas que cela soit genant pour l'exploitation de mon fichier.
Hum. Tu as le droit de le penser
Notre expérience du problème ici c'est qu'il vaut mieux indiquer un encodage qui correspond à ce que le fichier est réellement. JDom utilisé par une appli en java ici n'arrivait pas à relire les fichiers xml utf16 non annoncés, ou annonçant utf-8 mais en réalité en utf16.
Par contre de l'utf-16 qui annonce utf-16, plus de problème.
Pour info, on a écrit ailleurs un module qui produit des vrais fichiers en utf8 (puisqu'apparemment pbdom n'y arrive pas), si tu veux absolument avoir de l'utf-8 et que tu es intéressée par le code, yaka demander
wazou1812 a écrit:
C'est ce qu'il faut, sauf qu'il n'accepte pas le paramètre xml, j'ai l'erreur
Code:
Function Name : pbdom_element::SetAttribute(string strName, string strValue, string strNamespacePrefix, string strNamespaceUri, boolean bVerifyNamespace) Input NAMESPACE PREFIX is invalid.Car, si je mets "toto" à la place de "xml", cela fonctionne bien, mais le paramètre doit être facultatif, puisqu'en validant le fichier par w3c sans ce paramètre, je n'ai pas d'erreur, donc pour le moment, j'abandonne.
Coup de bol, dans ton DTD (si j'ai bien posé la bonne question à google ) on a
<!ATTLIST cXML version %string; "&cxml.version;" payloadID %string; #REQUIRED timestamp %datetime.tz; #REQUIRED signatureVersion %cxml.signatureVersions; #IMPLIED xml:lang %xmlLangCode; #IMPLIED >
Et justement le #IMPLIED à la ligne de xml:lang indique que c'est optionnel. Ça doit valider sans cet attribut.
wazou1812 a écrit:
J'ai donc essayé de supprimer ce paramètre, mais pour le moment, je n'y arrive pas.
J'ai essayé d'accéder à cette ligne, afin de la supprimer, et de la recréer avec les bons paramètres, mais toujours en vain,
Peut être une idée ?
Une idée non testée : avec RemoveAttribute sur ton document ? :
pbdom_PI.RemoveAttribute("xmlns")
Dernière modification par seki (28-09-2011 13:17:40)
Hors ligne
Une idée non testée : avec RemoveAttribute sur ton document ? :
pbdom_PI.RemoveAttribute("xmlns")
Cela ne fonctionne pas, car il ne consière pas "xmlns" comme un attribut.
function Name : pbdom_element::RemoveAttribute(string strAttributeName) Name starts with "xml".
Hors ligne
Bonjour,
En testant avec une autre méthode pour créer le document
PBDOM_DOCUMENT_SHIP = Create PBDOM_DOCUMENT PBDOM_DOCUMENT_SHIP.NewDocument ("cXML") pbdom_doctyp = Create PBDOM_DOCTYPE pbdom_doctyp.SetName ("cXML") pbdom_doctyp.setinternalsubset("http://....2.021/Fulfill.dtd") PBDOM_DOCUMENT_SHIP.SetDocType(pbdom_doctyp)
J'obtiens
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cXML [http://.....L/1.2.021/Fulfill.dtd]>
Avec cette méthode, il ne resterait plus qu'a trouver comment ajouter SYSTEM , et enlever ces de [ avant http://xxxxx
pour arriver au résultat attendu
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.021/Fulfill.dtd">
Hors ligne
wazou1812 a écrit:
Une idée non testée : avec RemoveAttribute sur ton document ? :
Code: pb
pbdom_PI.RemoveAttribute("xmlns")
Cela ne fonctionne pas, car il ne consière pas "xmlns" comme un attribut.Code:
function Name : pbdom_element::RemoveAttribute(string strAttributeName) Name starts with "xml".
Mouais. Avec GetAttribute / RemoveAttribute ça ne fonctionne pas non plus.
J'ai fini par l'avoir avec une version "brute force"
pbdom_document PBDOM_DOCUMENT_SHIP pbdom_element root pbdom_processinginstruction pbdom_PI pbdom_attribute attrs[], attr long i try PBDOM_DOCUMENT_SHIP = create pbdom_document PBDOM_DOCUMENT_SHIP.NewDocument ("", "", "cXML", "", "http://xml.cxml.org/schemas/cXML/1.2.021/Fulfill.dtd") //ajout du Processing instruction pbdom_PI = create PBDOM_ProcessingInstruction pbdom_PI.setname("xml") pbdom_PI.setvalue("version", "1.0") pbdom_PI.setvalue("encoding", "UTF-8") PBDOM_DOCUMENT_SHIP.addcontent(pbdom_PI) root = PBDOM_DOCUMENT_SHIP.GetRootElement() //positionnement de la root et de ses attributs root.SetAttribute("payloadID","xxx") root.SetAttribute("timestamp","xxx") root.SetAttribute("version","1.2.021") root.SetAttribute("lang", "en-FR") //marche pô //PBDOM_DOCUMENT_SHIP.GetRootElement().RemoveAttribute("xmlns") //marche pô non plus //attr = root.GetAttribute("xmlns") //root.RemoveAttribute(attr) //Gni ha ha haaa ^_^ root.GetAttributes(attrs[]) for i = 1 to upperbound(attrs[]) //messagebox("",attrs[i].GetName()) if attrs[i].GetName() = "xmlns" then root.RemoveAttribute(attrs[i]) //et paf! exit // for end if next PBDOM_DOCUMENT_SHIP.savedocument("c:\temp\pbdomtest.xml") destroy PBDOM_DOCUMENT_SHIP CATCH ( PBDOM_Exception pbde ) MessageBox( "PBDOM Exception", pbde.getMessage() ) CATCH ( PBXRuntimeError re ) MessageBox( "PBNI Exception", re.getMessage() ) end try
Hors ligne
seki a écrit:
wazou1812 a écrit:
Une idée non testée : avec RemoveAttribute sur ton document ? :
Code: pb
pbdom_PI.RemoveAttribute("xmlns")
Cela ne fonctionne pas, car il ne consière pas "xmlns" comme un attribut.Code:
function Name : pbdom_element::RemoveAttribute(string strAttributeName) Name starts with "xml".Mouais. Avec GetAttribute / RemoveAttribute ça ne fonctionne pas non plus.
J'ai fini par l'avoir avec une version "brute force"Code: pb
pbdom_document PBDOM_DOCUMENT_SHIP pbdom_element root pbdom_processinginstruction pbdom_PI pbdom_attribute attrs[], attr long i try PBDOM_DOCUMENT_SHIP = create pbdom_document PBDOM_DOCUMENT_SHIP.NewDocument ("", "", "cXML", "", "http://xml.cxml.org/schemas/cXML/1.2.021/Fulfill.dtd") //ajout du Processing instruction pbdom_PI = create PBDOM_ProcessingInstruction pbdom_PI.setname("xml") pbdom_PI.setvalue("version", "1.0") pbdom_PI.setvalue("encoding", "UTF-8") PBDOM_DOCUMENT_SHIP.addcontent(pbdom_PI) root = PBDOM_DOCUMENT_SHIP.GetRootElement() //positionnement de la root et de ses attributs root.SetAttribute("payloadID","xxx") root.SetAttribute("timestamp","xxx") root.SetAttribute("version","1.2.021") root.SetAttribute("lang", "en-FR") //marche pô //PBDOM_DOCUMENT_SHIP.GetRootElement().RemoveAttribute("xmlns") //marche pô non plus //attr = root.GetAttribute("xmlns") //root.RemoveAttribute(attr) //Gni ha ha haaa ^_^ root.GetAttributes(attrs[]) for i = 1 to upperbound(attrs[]) //messagebox("",attrs[i].GetName()) if attrs[i].GetName() = "xmlns" then root.RemoveAttribute(attrs[i]) //et paf! exit // for end if next PBDOM_DOCUMENT_SHIP.savedocument("c:\temp\pbdomtest.xml") destroy PBDOM_DOCUMENT_SHIP CATCH ( PBDOM_Exception pbde ) MessageBox( "PBDOM Exception", pbde.getMessage() ) CATCH ( PBXRuntimeError re ) MessageBox( "PBNI Exception", re.getMessage() ) end try
Merveilleux, que dis-je fantastique, un grand merci, pour cette aide très précieuse,
Hors ligne
Pages: 1