XMLTABLE : ne recevoir que la(les) première(s) valeur(s)

RPG (3 et 4, free), CL, SQL, etc...
Répondre
BrigitteG
Messages : 109
Enregistré le : jeu. 20 sept. 2012, 08:56:38

XMLTABLE : ne recevoir que la(les) première(s) valeur(s)

Message par BrigitteG »

Bonjour,

Mon but est de rechercher et d'extraire des valeurs contenues dans certaines balises d'un fichier xml. Certaines de ces balises peuvent être présente où non.
exemple :

Code : Tout sélectionner

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<ns3&#58;..........>
<Owner>
...
</Owner>
<NombreErreur>1</NombreErreur>
<Circulation>
<NumeroIdentifiantClient>xxxxx<NumeroIdentifiantClient>
<Anomalie>
<CodeAnoamlie>1</CodeAnoamlie>
<LibelleAnomalie>rrrrrrrrrrrrr </LibelleAnomalie>
</Anomalie>
</Circulation>
<Circulation>
<NumeroIdentifiantClient>xxxxx<NumeroIdentifiantClient>
</Circulation>
</ns3>

Sur l'IFS j'ai un fichier XML.
Je copie ce fichier avec
CPYFRMIMPF FROMSTMF('/XML/SIMOC.xml') TOFILE(LIB/TESTXML) MBROPT(*REPLACE) FROMCCSID(*FILE) TOCCSID(*FILE) RCDDLM(*LF) DTAFMT(*DLM) STRDLM(*NONE) RMVBLANK(*NONE) RPLNULLVAL(*FLDDFT)
dans un fichier créer par un crtpf.

Je peux lire mon fichier et faire un scan pour trouver

En cherchant un peu j'ai trouvé dans VOLUBIS ce code

Code : Tout sélectionner

dFileXml          s                   sqltype&#40;XML_DBCLOB&#58;2500&#41;    
d pos             s              5i 0                             
 /free                                                            
  exec sql                                                        
   select LIGNE into &#58;FileXml from lib/testxml1;                
   pos = %scan&#40;%ucs2&#40;'Circulation'&#41; &#58; FileXml_data&#41;;                                                 
   *inlr = *on;                                                   
 /end-free
Mais à ce niveau j'ai zero dans pos alors que j'ai bien la balise <Circulation> dans fichier xml.
Donc je me demande si mon fichier doit être créer par un crtpf ou autrement ?

Demande supplémentaire : dans sqltype(XML_DBCLOB:2500) à quoi correspond la valeur 2500 ?

Merci d'avance pour vos réponses.
Modifié en dernier par BrigitteG le ven. 09 mai 2014, 12:26:38, modifié 2 fois.

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

CREATE TBALE et non CRTPF

Message par cmasse »

SI vous lisez complétement le cours vous verrez qu'il parle de champs de type XML et non CHAR, ceci n'est possible qu'avec CREATE TABLE, DDS (et donc CRTPF) n'ayant subit AUCUNE avancée depuis .... 1992 !

PS : 2500 est la taille de la variable pour recevoir la zone de type CLOB ou XML (en octets)
Christian Massé (Volubis.fr)

BrigitteG
Messages : 109
Enregistré le : jeu. 20 sept. 2012, 08:56:38

Comment créer un fichier DB2 chargé avec du xml et le lire

Message par BrigitteG »

Bonjour,
Après avoir créer ma table

Code : Tout sélectionner

create  table  fxml  &#40;
              nbr  bigint  generated  always  as  identity
                                      &#40;start  with  1  increment  by  1  nocycle&#41;,
              doc  xml  ,
              primary  key  &#40;nbr&#41;&#41;
j'insert les données du xml qui se trouve dans l'ifs

Code : Tout sélectionner

 insert into fxml&#40;doc&#41; values&#40;get_xml_file&#40;'/GIRARDIN/XML/SIMOC.xml'&#41;&#41;
ensuite je veux afficher les données et là je rencontre des soucis :

1er cas exemple xml

Code : Tout sélectionner


<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<ns3&#58;xxxxxxx xsi&#58;schemaLocation="urn&#58;fr&#58;xxx&#58;xxx&#58;xx&#58;xxxxx.XSD xmlns&#58;ns3="http&#58;//www.xxxx.fr/XML/Schema" xmlns&#58;xsi="http&#58;//www.w3.org/2001/XMLSchema-instance">
<Circulation>
   <Identifiant>123456</Identifiant> 
        <Chargement>
               <Exploitation>
			<Immatriculation>
				<Identifiant>AABBCC</Identifiant>
			</Immatriculation>
	     </Exploitation>
	</Chargement>
</Circulation>
</ns3&#58;xxxxx>

Code : Tout sélectionner

SELECT X.* 
FROM fxml, 
XMLTABLE &#40;'$d/ns3&#58;xxxxxxx xsi&#58;schemaLocation="urn&#58;fr&#58;xxx&#58;xxx&#58;xx&#58;xxxxx.XSD xmlns&#58;ns3="http&#58;//www.xxxx.fr/XML/Schema" xmlns&#58;xsi="http&#58;//www.w3.org/2001/XMLSchema-instance"/Circulation' passing doc as "d" 
   COLUMNS 
 Circulation	VARCHAR&#40;40&#41;	path'Identifiant',
   Document 	VARCHAR&#40;40&#41;	PATH 'Chargement/Exploitation/Immatriculation/Identifiant'
 &#41; AS X
Dans ce cas-là j'ai une erreur sql Etat SQL : 10505 Code fournisseur : -16002
A priori c'est la partie ns3:.... qui pose problème.

Comment faut-il déclarer la partie ns3:.... ?

2ème cas pour pouvoir faire des tests j'ai modifié le xml

Code : Tout sélectionner

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<ns3>
   <Circulation>
     <Identifiant>123456</Identifiant> 
        <Chargement>
              <Exploitation>
			<Immatriculation>
				<Identifiant>AABBCC</Identifiant>
			</Immatriculation>
	    </Exploitation>
	</Chargement>
  </Circulation>
  <Circulation>
     <Identifiant>98598</Identifiant> 
        <Chargement>
              <Exploitation>
			<Immatriculation>
				<Identifiant>AA12345</Identifiant>
			</Immatriculation>
                       <Immatriculation>
				<Identifiant>AA8989</Identifiant>
			</Immatriculation>
             </Exploitation>
	</Chargement>
   </Circulation>
</ns3>

Code : Tout sélectionner

SELECT X.* 
FROM fxml, 
XMLTABLE &#40;'$d/ns3/Circulation' passing doc as "d" 
   COLUMNS 
 Circulation	VARCHAR&#40;40&#41;	path'Identifiant',
   Document 	VARCHAR&#40;40&#41;	PATH 'Chargement/Exploitation/Immatriculation/Identifiant'
 &#41; AS X
Ici le problème est différent, j'ai bien la première circulation, mais pas la seconde car j'ai deux fois la partie immatriculation/identifiant ce qui génère une erreur sql

Code : Tout sélectionner

Circulation  Document
123456       AABBCC
si je déclare la zone document en xml au lieu de VARCHAR(40) j'obtiens

Code : Tout sélectionner

Circulation  Document
123456       <Identifiant>AABBCC</Identifiant>
98598         <Identifiant>AA12345</Identifiant><Identifiant>AA8989</Identifiant>
Pour information, le fichier xml est reçu et donc nous ne sommes pas mettre de son schéma.

Qu'elle est la solution pour ne récupérer que le premier identifiant.

Merci pour votre aide

BrigitteG
Messages : 109
Enregistré le : jeu. 20 sept. 2012, 08:56:38

Comment créer un fichier DB2 chargé avec du xml et le lire

Message par BrigitteG »

A priori pour le 1er cas, il suffirait d'écrire de cette façon.

Code : Tout sélectionner

SELECT X.* 
FROM fxml, 
XMLTABLE &#40;'$d//Circulation' passing doc as "d" 
   COLUMNS 
 Circulation	VARCHAR&#40;40&#41;	path'Identifiant',
   Document 	VARCHAR&#40;40&#41;	PATH 'Chargement/Exploitation/Immatriculation/Identifiant'
 &#41; AS X
Par contre j'ai toujours le pb du 2ème cas.

cmasse
Site Admin
Messages : 813
Enregistré le : mer. 14 févr. 2007, 18:00:03
Localisation : Nantes
Contact :

SQ16003

Message par cmasse »

Extrait de notre cours


S'il existe plusieurs numéros de téléphone, par exemple :

INSERT INTO Customer (Cid, Info) VALUES (1000,
'<customerinfo Cid="1005">
<name>Helen SUE</name>
<addr country="US"><street>1596 Sunset BD</street>
<city>L.A</city>
<prov-state>California</prov-state>
<pcode-zip>123456</pcode-zip>
</addr>
<phone type="work">999-555-1111</phone>
<phone type="home">999-111-4444</phone>
</customerinfo>


la fonction XMLTABLE ne peut pas mettre une série de valeur dans UNE colonne, vous recevez SQ16003

SELECT X.nom ,x.rue, x.ville, x.TEL
FROM posample/Customer,
XMLTABLE (
XMLNAMESPACES(DEFAULT 'http://posample.org'),
'$c/customerinfo' passing INFO as "c"
COLUMNS
NOM CHAR(30) PATH 'name',
RUE VARCHAR(25) PATH 'addr/street',
VILLE VARCHAR(25) PATH 'addr/city',
TEL char(10) PATH 'phone'
) AS X


vous pouvez alors :

->ne recevoir que la(les) première(s) valeur(s)

Ecrivez

SELECT X.nom ,x.rue, x.ville, x.TEL
FROM posample/Customer,
XMLTABLE (
XMLNAMESPACES(DEFAULT 'http://posample.org'),
'$c/customerinfo' passing INFO as "c"
COLUMNS
NOM CHAR(30) PATH 'name',
RUE VARCHAR(25) PATH 'addr/street',
VILLE VARCHAR(25) PATH 'addr/city',
TEL char(10) PATH 'phone[1]'
) AS X

->retourner la totalité des téléphones sous forme XML (ce que vous avez fait)


-> retourner chaque téléphone avec la syntaxe suivante


SELECT X.nom ,x.rue, x.ville, x.TEL
FROM posample.Customer,
XMLTABLE (
XMLNAMESPACES(DEFAULT 'http://posample.org'),
'$c/customerinfo/phone' passing INFO as "c"
COLUMNS
NOM CHAR(30) PATH '../name',
RUE VARCHAR(25) PATH '../addr/street',
VILLE VARCHAR(25) PATH '../addr/city',
TEL char(20) PATH '.'
) AS X

je pense que c'est cette dernière syntaxe qui va vous apporter la solution.
Christian Massé (Volubis.fr)

BrigitteG
Messages : 109
Enregistré le : jeu. 20 sept. 2012, 08:56:38

Comment créer un fichier DB2 chargé avec du xml et le lire

Message par BrigitteG »

Merci c'est bien la dernière syntaxe qui me donne la solution.

BrigitteG
Messages : 109
Enregistré le : jeu. 20 sept. 2012, 08:56:38

XMLTABLE : ne recevoir que la(les) première(s) valeur(s)

Message par BrigitteG »

Bonjour,
Voulant appliquer cette option (ne recevoir que la(les) première(s) valeur(s)) à mon cas, je rencontre un problème.

Je n'arrive pas à récupérer les lignes voulues :

Code : Tout sélectionner

Circu		Num
123456	AABBCC	
98598	AA12345	

Fichier xml

Code : Tout sélectionner

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> 
 <ns3> 
    <Circulation> 
      <Identifiant>123456</Identifiant> 
         <Chargement> 
           <Exploitation> 
            <Immatriculation> 
             <Identifiant>AABBCC</Identifiant> 
            </Immatriculation> 
          </Exploitation> 
       </Chargement> 
    </Circulation> 
   <Circulation> 
      <Identifiant>98598</Identifiant> 
         <Chargement> 
          <Exploitation> 
           <Immatriculation> 
             <Identifiant>AA12345</Identifiant> 
            </Immatriculation> 
            <Immatriculation> 
             <Identifiant>AA8989</Identifiant> 
            </Immatriculation> 
          </Exploitation> 
    </Chargement> 
    </Circulation> 
 </ns3> 


1ère écriture

Code : Tout sélectionner

SELECT X.* 
FROM fxml, 
XMLTABLE &#40;'$doc//Circulation' passing doc as "doc" 
   COLUMNS 
 Circu		VARCHAR&#40;40&#41;	path 'Identifiant',
  Num		VARCHAR&#40;40&#41;	PATH 'Chargement/Exploitation/Immatriculation/Identifiant&#91;1&#93;'
 &#41; AS X
Résultat

Code : Tout sélectionner

Circu		Num
123456	AABBCC
2è écriture

Code : Tout sélectionner

SELECT X.* 
FROM fxml, 
XMLTABLE &#40;'$doc//Circulation/Chargement/Exploitation/Immatriculation' passing doc as "doc" 
   COLUMNS 
 Circu	VARCHAR&#40;40&#41;	path '../../../Identifiant',
 Num 	VARCHAR&#40;40&#41;	PATH 'Identifiant&#91;1&#93;'
 &#41; AS X
Résultat

Code : Tout sélectionner

Circu		Num
123456	AABBCC	
98598	AA12345	
98598	AA8989	
J'ai regardé le cours mais je n'arrive pas à voir mon erreur.

Merci d'avance pour votre aide.

Répondre