Pas de problème (pb), que du PowerBuilder (PB) ^^

Le forum (ô combien francophone) des utilisateurs de Powerbuilder.

Recherche rapide

Annonce

Certaines rubriques, dont des cours, sont uniquement visibles par les membres du forum ^^.
Dans la rubrique Liens & Références, vous avez accès à un sommaire de téléchargement, profitez-en !
Il existe maintenant un nouveau TOPIC "Votre CV en Ligne" accessible uniquement par demande.
  • Index
  •  » Powerscripts
  •  » [RESOLU] XML : supprimer des balises vides avec pbdom

#1 01-06-2012 14:16:17

wazou1812  
Modératrice
Award: bf
Date d'inscription: 24-05-2006
Messages: 610
Pépites: 2,097
Banque: 3,536,631,712,504

[RESOLU] XML : supprimer des balises vides avec pbdom

Bonjour,

J'ai construit des fichiers XML via la datawindow de pb avec le template.

Pour les besoins, j'utilise des sous report, qui ont pour conséquence de me positionner des balises vide (ce qui n'est normalement pas gênant en XML je vous l'accorde).

Mais je dois supprimer certaines balises vides pour valider mon fichier xml.

Par exemple, sous l’élément "InvoiceLine", je peux retrouver n balises "Harware" qui sont vides.

J'ai bien essayé d'utiliser "Getcontent" , "hasChilden" , et "RemoveChildElement("Harware")" , mais il ne me supprimer que le 1er élément rencontré et ne trouve pas les autres.

Donc 2 questions , :
1°) Est-il possible de ne pas positionner les balises vides en xml ?

2°) Auriez-vous une piste pour supprimer l'ensemble des éléments qui ne contiennent aucun enregistrement ?

J'espère avoir été claire ? et merci d'avance pour vos lumières,

ci dessous, un extrait de mon fichier xml avec la balise que je veux supprimer.

Code: pb

    <InvoiceLine>
      <InvoiceLineNumber/>
      <LineCode>GROUPEMENT 1</LineCode>
      <FullLineDescription/>
      <Quantity>0</Quantity>
      <UnitPrice>0</UnitPrice>
      <LineValue>9983.11</LineValue>
      <LineComment/>
      <LineTax>
        <TaxCode>04</TaxCode>
        <TaxRate>19.60</TaxRate>
        <TaxValue>1956.68</TaxValue>
      </LineTax>
      <LineValueWithTax>11939.79</LineValueWithTax>
      <DiscountRate>0</DiscountRate>
      <NetUnitPrice>0</NetUnitPrice>
      <SpecialTax/>
      <Serial>
      </Serial>
      <Harware/>


PB 12.1 build 7000

Hors ligne

 

#2 01-06-2012 22:46:35

xlat  
0xc0000005
Award: bf
Lieu: Tanger (طنج)
Date d'inscription: 04-12-2010
Messages: 720
Pépites: 11,343
Banque: 100,221,387,868,884,300
Site web

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

wazou1812 a écrit:

...
J'ai bien essayé d'utiliser "Getcontent" , "hasChilden" , et "RemoveChildElement("Harware")" , mais il ne me supprimer que le 1er élément rencontré et ne trouve pas les autres.
...

Bonjour, et avec  RemoveChildElements ça donne quoi ? (attention il faut bien boucler sur tout les éléments InvoiceLine).


https://lut.im/eJINqa9o/vAtyxD0h "Don't believe everything you read on the Internet"
    -- Abraham Lincoln

www.ngs.ma

Hors ligne

 

#3 04-06-2012 07:30:32

wazou1812  
Modératrice
Award: bf
Date d'inscription: 24-05-2006
Messages: 610
Pépites: 2,097
Banque: 3,536,631,712,504

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

xlat a écrit:

wazou1812 a écrit:

...
J'ai bien essayé d'utiliser "Getcontent" , "hasChilden" , et "RemoveChildElement("Harware")" , mais il ne me supprimer que le 1er élément rencontré et ne trouve pas les autres.
...

Bonjour, et avec  RemoveChildElements ça donne quoi ? (attention il faut bien boucler sur tout les éléments InvoiceLine).

Bonjour,

Le problème est que je veux supprimer la balise 'Harware', uniquement si elle est vide, j'ai donc fait ce bout de code, mais qui ne supprime que la 1ère balise vide 'Hardware' se trouvant sous la balise InvoiceLine.

J'ai du loupé quelque chose, mais ou ?

Code: pb


PBDOM_Object      pbdom_obj_array[]  
long ll_row
 

TRY
  
  i_PBDOM_DOCUMENT_COMPLET.GetRootElement().GetChildElement("Invoice").GetChildElement("Module").GetChildElement ("InvoiceLine").GetContent(pbdom_obj_array)
    
    
  For ll_row = 1 to upperbound(pbdom_obj_array[])
    
    
    If i_PBDOM_DOCUMENT_COMPLET.GetRootElement().GetChildElement("Invoice").GetChildElement("Module").GetChildElement ("InvoiceLine").GetChildElement ("Harware").HasChildren() = false then
    End if
    
    
    If i_PBDOM_DOCUMENT_COMPLET.GetRootElement().GetChildElement("Invoice").GetChildElement("Module").GetChildElement ("InvoiceLine").GetChildElement ("Harware").HasChildren() = false then
      i_PBDOM_DOCUMENT_COMPLET.GetRootElement().GetChildElement("Invoice").GetChildElement("Module").GetChildElement ("InvoiceLine").RemoveChildElement("Harware")
    End if
    
    
  NEXT  
 

  CATCH (pbdom_exception ex1)
    Invo_batchs.nvuf_ecriture_batchlog(" !!! Erreur sur la suppression de balise Harware (af_suppression_balise) " + ex1.getMessage() )
    return -1
END TRY


return 0


Si vous avez une petite idée ? Je veux bien, merci d'avance

Hors ligne

 

#4 04-06-2012 09:42:27

seki  
0x73656B69
Award: bf
Lieu: Laquenexy & Luxembourg
Date d'inscription: 20-11-2008
Messages: 1118
Pépites: 4,296,080,204
Banque: 9,223,372,036,854,776,000
Site web

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

wazou1812 a écrit:

Si vous avez une petite idée ? Je veux bien, merci d'avance

J'ai brodé sur ton code comme suit (comme je ne connais pas précisément tes specs, je teste les attributs et le contenu pour savoir si "Harware" n'est pas vide) :

Code: pb

PBDOM_BUILDER pbdombuilder
PBDOM_Document i_PBDOM_DOCUMENT_COMPLET
PBDOM_Element pbdomelem
PBDOM_Element pbdomelements[]
Long ll_row

pbdombuilder = create PBDOM_BUILDER

try
  
  i_PBDOM_DOCUMENT_COMPLET = pbdombuilder.buildfromfile("invoice.xml")
  
  //la ligne qui suit est remplacée par plusieurs pour aider le debuggage
  //i_PBDOM_DOCUMENT_COMPLET.GetRootElement().GetChildElement("Invoice").GetChildElement("Module").GetChildElement ("InvoiceLine").GetContent(pbdom_obj_array)

  //Attention, je ne teste jamais si pbdomelem est trouvé (not null)... ;)

  pbdomelem = i_PBDOM_DOCUMENT_COMPLET.GetRootElement()
  //(dans mon fichier Invoice est le root) pbdomelem = pbdomelem.GetChildElement("Invoice")
  pbdomelem = pbdomelem.GetChildElement("Module")
  pbdomelem = pbdomelem.GetChildElement ("InvoiceLine")
  pbdomelem.GetChildElements("Harware", pbdomelements[])
  
  for ll_row = 1 to UpperBound(pbdomelements[])  
    
    if not pbdomelements[ll_row].HasChildren() and not pbdomelements[ll_row].HasAttributes() then
      pbdomelem.RemoveContent(pbdomelements[ll_row])
    end if
    
  next
  
  i_PBDOM_DOCUMENT_COMPLET.SaveDocument("filtered.xml")
  
Catch (pbdom_exception ex1)
  MessageBox("Erreur", " !!! Erreur sur la suppression de balise Harware (af_suppression_balise) " + ex1.getMessage() )
  return -1
end try
destroy pbdombuilder

return 0


avec un fichier des test

Code: xml

<Invoice>
    <Module>
        <InvoiceLine>
              <InvoiceLineNumber/>
              <LineCode>GROUPEMENT 1</LineCode>
              <FullLineDescription/>
              <Quantity>0</Quantity>
              <UnitPrice>0</UnitPrice>
              <LineValue>9983.11</LineValue>
              <LineComment/>
              <LineTax>
                <TaxCode>04</TaxCode>
                <TaxRate>19.60</TaxRate>
                <TaxValue>1956.68</TaxValue>
              </LineTax>
              <LineValueWithTax>11939.79</LineValueWithTax>
              <DiscountRate>0</DiscountRate>
              <NetUnitPrice>0</NetUnitPrice>
              <SpecialTax/>
              <Serial>
              </Serial>
              <Harware/>
              <Harware/>
              <Harware someattrib=""/>
              <Harware/>
              <Harware>some content</Harware>
              <Harware/>
        </InvoiceLine>
    </Module>
</Invoice>

j'obtiens le fichier suivant (étonnamment, les éléments supprimés semble laisser un espace dans le fichier, j'espère que cela ne te gène pas ?), ça semble fonctionner (testé sur du PB11.5) :

Code: xml

<Invoice>
    <Module>
        <InvoiceLine>
              <InvoiceLineNumber/>
              <LineCode>GROUPEMENT 1</LineCode>
              <FullLineDescription/>
              <Quantity>0</Quantity>
              <UnitPrice>0</UnitPrice>
              <LineValue>9983.11</LineValue>
              <LineComment/>
              <LineTax>
                <TaxCode>04</TaxCode>
                <TaxRate>19.60</TaxRate>
                <TaxValue>1956.68</TaxValue>
              </LineTax>
              <LineValueWithTax>11939.79</LineValueWithTax>
              <DiscountRate>0</DiscountRate>
              <NetUnitPrice>0</NetUnitPrice>
              <SpecialTax/>
              <Serial>
              </Serial>
              
              
              <Harware someattrib=""/>
              
              <Harware>some content</Harware>
              
        </InvoiceLine>
    </Module>
</Invoice>

The best programs are the ones written when the programmer is supposed to be working on something else. - Melinda Varian

Mes réponses PB sur StackOverflow
http://stackoverflow.com/users/flair/317266.png

Hors ligne

 

#5 04-06-2012 10:54:28

wazou1812  
Modératrice
Award: bf
Date d'inscription: 24-05-2006
Messages: 610
Pépites: 2,097
Banque: 3,536,631,712,504

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

Bonjour,

Un grand merci, cela fonctionne à merveille, et en plus j'ai compris mon erreur de parsing, on avance, doucement mais surement,

Hors ligne

 

#6 04-06-2012 13:48:22

seki  
0x73656B69
Award: bf
Lieu: Laquenexy & Luxembourg
Date d'inscription: 20-11-2008
Messages: 1118
Pépites: 4,296,080,204
Banque: 9,223,372,036,854,776,000
Site web

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

wazou1812 a écrit:

Code: pb

//...
For ll_row = 1 to upperbound(pbdom_obj_array[])
  If i_PBDOM_DOCUMENT_COMPLET.GetRootElement().GetChildElement("Invoice").GetChildElement("Module").GetChildElement ("InvoiceLine").GetChildElement ("Harware").HasChildren() = false then
      i_PBDOM_DOCUMENT_COMPLET.GetRootElement().GetChildElement("Invoice").GetChildElement("Module").GetChildElement ("InvoiceLine").RemoveChildElement("Harware")
  End if
NEXT  

J'ai oublié de préciser un point : je ne connais pas la longueur et la complexité des documents qui sont traités par ton code, mais de manière générale, il vaudrait mieux
- stocker une fois l'élément pour lequel on veut supprimer des sous-éléments dans une variable
- réutiliser cette variable pour le if et pour le Remove()

Plutôt que se retaper 1 ou 2x GetRoot().get().get().get().get()... à chaque tour de boucle. Ça doit finir par faire une différence de perfs visible au bout de quelques itérations, sachant que PBDOM est une extension PBNI et qu'on saute entre PB et l'extension à chaque appel et chaque retour de méthode... Enfin c'est juste mon avis


The best programs are the ones written when the programmer is supposed to be working on something else. - Melinda Varian

Mes réponses PB sur StackOverflow
http://stackoverflow.com/users/flair/317266.png

Hors ligne

 

#7 04-06-2012 15:09:27

wazou1812  
Modératrice
Award: bf
Date d'inscription: 24-05-2006
Messages: 610
Pépites: 2,097
Banque: 3,536,631,712,504

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

Merci Seki pour ces précisions.

J'étais effectivement repartie de ton code pour finaliser le mien , en mettant dans la variable uniquement la partie de l'arbre qui m'interesse.

En l’occurrence, il s'agit de factures client, avec une facture par fichier XML,

Encore merci pour ces précieux conseils,

Hors ligne

 

#8 05-07-2012 16:45:42

wazou1812  
Modératrice
Award: bf
Date d'inscription: 24-05-2006
Messages: 610
Pépites: 2,097
Banque: 3,536,631,712,504

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

Bonjour,

Encore une petite manipulation des fichiers pbdom que je n'arrive pas à faire.

une partie de mon fichier est ainsi

Code:

    <MailingAddressBuyer>
      <CompanyName/>
      <BillingManager/>
      <Address1/>
      <Address2/>
      <Address3/>
      <City/>
      <Postcode/>
      <Country/>
    </MailingAddressBuyer>

Avec l'ensemble du contenu vide.

Le résultat attendu voudrait que dans ce cas, l'ensemble de la balise <MailingAddressBuyer> n'apparaisse pas dans le fichier xml final.
Fonctionnellement, si l'élément <CompanyName/> est vide, nous pouvons considérer que la balise <MailingAddressBuyer> est à supprimer.

J'ai eu beau retourner le pb dans tous les sens, pas moyen d'arriver au résultat attendu.

Auriez-vous une petite idée ?

Merci d'avance,

Hors ligne

 

#9 06-07-2012 09:34:35

wazou1812  
Modératrice
Award: bf
Date d'inscription: 24-05-2006
Messages: 610
Pépites: 2,097
Banque: 3,536,631,712,504

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

Bonjour,


Pour vous aider dans votre recherche, voici un extrait complet du fichier xml, l'objectif étant de supprimer l'élément MailingAddressBuyer dans son ensemble , si au moins le 1er element est vide.

Merci d'avance pour votre aide,

Code:

<?xml version="1.0" encoding="UTF-16LE" standalone="yes"?>
<Invoice>
  <DocumentNumber>60809</DocumentNumber>
  <DocumentLanguage>FR</DocumentLanguage>
  <VATExemption>N</VATExemption>
  <Supplier>
    <phoneNumber>+33 1 69 00 00 00</phoneNumber>
    <FaxNumber>+33 1 69 00 00 00</FaxNumber>
    <Web>www.TOTO.fr</Web>
    <Capital>9999.00</Capital>
    <LegalForm>SAS</LegalForm>
    <Agency/>
    <AddressSupplier>
      <Address1>1, Rue de Terre Neuve</Address1>
      <Address2>Les Ulis . CS60062</Address2>
      <Address3/>
      <City>Courtaboeuf cedex</City>
      <Postcode>91978</Postcode>
      <Country>France</Country>
    </AddressSupplier>
    <ContactSupplier>
      <ContactId/>
      <ContactName>HENNEQUIN DENIS</ContactName>
      <ContactPhone>0033 169182032</ContactPhone>
    </ContactSupplier>
  </Supplier>
  <Buyer>
    <VATRegistrationId>55555</VATRegistrationId>
    <Siret>55555</Siret>
    <Name>TEST</Name>
    <AddressBuyer>
      <Address1>SERVICE FACTURIER</Address1>
      <Address2>13  Pl VENDOME</Address2>
      <Address3>GA JUST 2</Address3>
      <City>PARIS CDX 1</City>
      <Postcode>75042</Postcode>
      <Country>France</Country>
    </AddressBuyer>
    <MailingAddressBuyer>
      <Address1/>
      <Address2/>
      <Address3/>
      <City/>
      <Postcode/>
      <Country/>
    </MailingAddressBuyer>
    <ECSReference>900152</ECSReference>
  </Buyer>
</Invoice>

Hors ligne

 

#10 06-07-2012 13:29:59

xlat  
0xc0000005
Award: bf
Lieu: Tanger (طنج)
Date d'inscription: 04-12-2010
Messages: 720
Pépites: 11,343
Banque: 100,221,387,868,884,300
Site web

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

Salut,
tu peux utiliser GetElementsByTagName('MailingAddressBuyer'), puis sur chaque noeud MailingAddressBuyer
regarder le texte de l'enfant 'Address1', si il est vide alors appel Detach sur le noeaud MailingAddressBuyer.

Voici un exemple à remanier :-p

>pbperl115 +pbdom115.pbd -MPowerbuilder=:all trimtag.pl

Code: pbperl

#trimtag.pl
$builder = Create(pbdom_builder);
$doc = $builder->BuildFromFile('sample.xml');
$doc->GetElementsByTagName('MailingAddressBuyer', \@elts );
$_->Detach 
  foreach 
  grep{ 
    my $child=$_->GetChildElement('Address1'); 
    defined $child 
    and $child->GetText eq '' 
  } @elts;
print $doc->SaveDocumentIntoString;


ce qui donne :

Code: xml

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Invoice>
  <DocumentNumber>60809</DocumentNumber>
  <DocumentLanguage>FR</DocumentLanguage>
  <VATExemption>N</VATExemption>
  <Supplier>
    <phoneNumber>+33 1 69 00 00 00</phoneNumber>
    <FaxNumber>+33 1 69 00 00 00</FaxNumber>
    <Web>www.TOTO.fr</Web>
    <Capital>9999.00</Capital>
    <LegalForm>SAS</LegalForm>
    <Agency/>
    <AddressSupplier>
      <Address1>1, Rue de Terre Neuve</Address1>
      <Address2>Les Ulis . CS60062</Address2>
      <Address3/>
      <City>Courtaboeuf cedex</City>
      <Postcode>91978</Postcode>
      <Country>France</Country>
    </AddressSupplier>
    <ContactSupplier>
      <ContactId/>
      <ContactName>HENNEQUIN DENIS</ContactName>
      <ContactPhone>0033 169182032</ContactPhone>
    </ContactSupplier>
  </Supplier>
  <Buyer>
    <VATRegistrationId>55555</VATRegistrationId>
    <Siret>55555</Siret>
    <Name>TEST</Name>
    <AddressBuyer>
      <Address1>SERVICE FACTURIER</Address1>
      <Address2>13  Pl VENDOME</Address2>
      <Address3>GA JUST 2</Address3>
      <City>PARIS CDX 1</City>
      <Postcode>75042</Postcode>
      <Country>France</Country>
    </AddressBuyer>

    <ECSReference>900152</ECSReference>
  </Buyer>
</Invoice>

Dernière modification par xlat (06-07-2012 13:30:48)


https://lut.im/eJINqa9o/vAtyxD0h "Don't believe everything you read on the Internet"
    -- Abraham Lincoln

www.ngs.ma

Hors ligne

 

#11 09-07-2012 08:33:29

seki  
0x73656B69
Award: bf
Lieu: Laquenexy & Luxembourg
Date d'inscription: 20-11-2008
Messages: 1118
Pépites: 4,296,080,204
Banque: 9,223,372,036,854,776,000
Site web

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

xlat a écrit:

Code: pbperl

#trimtag.pl
[...]

Prosélytisme !


The best programs are the ones written when the programmer is supposed to be working on something else. - Melinda Varian

Mes réponses PB sur StackOverflow
http://stackoverflow.com/users/flair/317266.png

Hors ligne

 

#12 07-08-2012 09:13:11

wazou1812  
Modératrice
Award: bf
Date d'inscription: 24-05-2006
Messages: 610
Pépites: 2,097
Banque: 3,536,631,712,504

Re: [RESOLU] XML : supprimer des balises vides avec pbdom

xlat a écrit:

Salut,
tu peux utiliser GetElementsByTagName('MailingAddressBuyer'), puis sur chaque noeud MailingAddressBuyer
regarder le texte de l'enfant 'Address1', si il est vide alors appel Detach sur le noeaud MailingAddressBuyer.

Voici un exemple à remanier :-p

>pbperl115 +pbdom115.pbd -MPowerbuilder=:all trimtag.pl

Code: pbperl

#trimtag.pl
$builder = Create(pbdom_builder);
$doc = $builder->BuildFromFile('sample.xml');
$doc->GetElementsByTagName('MailingAddressBuyer', \@elts );
$_->Detach 
  foreach 
  grep{ 
    my $child=$_->GetChildElement('Address1'); 
    defined $child 
    and $child->GetText eq '' 
  } @elts;
print $doc->SaveDocumentIntoString;


ce qui donne :

Code: xml

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Invoice>
  <DocumentNumber>60809</DocumentNumber>
  <DocumentLanguage>FR</DocumentLanguage>
  <VATExemption>N</VATExemption>
  <Supplier>
    <phoneNumber>+33 1 69 00 00 00</phoneNumber>
    <FaxNumber>+33 1 69 00 00 00</FaxNumber>
    <Web>www.TOTO.fr</Web>
    <Capital>9999.00</Capital>
    <LegalForm>SAS</LegalForm>
    <Agency/>
    <AddressSupplier>
      <Address1>1, Rue de Terre Neuve</Address1>
      <Address2>Les Ulis . CS60062</Address2>
      <Address3/>
      <City>Courtaboeuf cedex</City>
      <Postcode>91978</Postcode>
      <Country>France</Country>
    </AddressSupplier>
    <ContactSupplier>
      <ContactId/>
      <ContactName>HENNEQUIN DENIS</ContactName>
      <ContactPhone>0033 169182032</ContactPhone>
    </ContactSupplier>
  </Supplier>
  <Buyer>
    <VATRegistrationId>55555</VATRegistrationId>
    <Siret>55555</Siret>
    <Name>TEST</Name>
    <AddressBuyer>
      <Address1>SERVICE FACTURIER</Address1>
      <Address2>13  Pl VENDOME</Address2>
      <Address3>GA JUST 2</Address3>
      <City>PARIS CDX 1</City>
      <Postcode>75042</Postcode>
      <Country>France</Country>
    </AddressBuyer>

    <ECSReference>900152</ECSReference>
  </Buyer>
</Invoice>

Bonjour,

Tout d'abord, merci pour ton retour.

Désolée pour la réponse un peu tardive, mais congés + autres priorités ont retardé ma réponse.

Et effectivement, j'avais zappé la fonctionnalité 'detach' qui effectivement fonctionne très bien dans ce cas.

Encore merci, sujet RESOLU,

Hors ligne

 
  • Index
  •  » Powerscripts
  •  » [RESOLU] XML : supprimer des balises vides avec pbdom

Pied de page des forums

Propulsé par FluxBB 1.2.22