Structure XML via publication

Bonjour,

Je fais un export XML en utilisant une publication et le code suivant :

<entites>
[BEGIN]
	<entite>
	<participationType>[VALUE:ParticipationEntiteTypePart]</participationType>
	<direction>[VALUE:ParticipationService_ParticipationDirection_fk.participationDirectionLibelle]</direction>
	<raison_sociale>[VALUE:ParticipationEntiteRaison]</raison_sociale>
	<service_suivi>[VALUE:participationServiceLibelle]</service_suivi>
	<pers_morale_type>[VALUE:ParticipationEntiteTypePers]</pers_morale_type>
	<siege_adrs>[VALUE:ParticipationEntiteAdresse]</siege_adrs>
	<siege_adrs_no>[VALUE:participationEntiteAdresseNumero]</siege_adrs_no>	
	<siege_npa>[VALUE:participationEntiteAdresseCp]</siege_npa>
	<siege_commune>[VALUE:participationEntiteAdressCommune]</siege_commune>
	<objectifStrat1>[VALUE:ParticipationEntiteObj1]</objectifStrat1>
	<objectifStrat2>[VALUE:ParticipationEntiteObj2]</objectifStrat2>
	<objectifStrat3>[VALUE:ParticipationEntiteObj3]</objectifStrat3>
	<objectifStrat4>[VALUE:ParticipationEntiteObj4]</objectifStrat4>
	<objectifStrat5>[VALUE:ParticipationEntiteObj5]</objectifStrat5>
	<mandats>
		<mandat>
			[BEGIN:ParticipationMandat:ParticipationMandat_ParticipationEntite_fk]
				<representant>[VALUE:ParticipationMandat_ParticipationRepresentant_fk.participationReprNom], [ParticipationMandat_ParticipationRepresentant_fk.participationReprPrenom]</representant>
				<fonctionVille>[VALUE:ParticipationRepresentant_ParticipationFonction_fk.participationFonctionNom]</fonctionVille>
				<fonctionMandat>[VALUE:participationMandatFonction]</fonctionMandat>
				<mandatArchive>[VALUE:participationMandatArchive]</mandatArchive>
			[END:ParticipationMandat]	
		</mandat>
	</mandats>
	<cautionnements>
		<cautionnement>
			[BEGIN:ParticipationCautionnement:ParticipationCautionnement_ParticipationEntite_fk]
				<cautionnementNom>[VALUE:participationCautionnementId]</cautionnementNom>
				<cautionnementMontantIni>[VALUE:participationCautionnementMontantIni]</cautionnementMontantIni>
			[END:ParticipationCautionnement]	
		</cautionnement>
	</cautionnements>
	
	</entite>
[END]	
</entites>

la structure obtenue n’est pas tout é fait ce que je voudrais au niveau des boucles sur mandats et sur cautionnement

Exemple avec mandat :
Résultat :

                 <mandats>
                               <mandat>
                                                               <representant>Pidoux, Jean-Yves</representant>
                                                               <fonctionVille>Conseiller municipal SIL</fonctionVille>
                                                               <fonctionMandat>Président du conseil d'administration</fonctionMandat>
                                                               <mandatArchive>Actif</mandatArchive>

                                                               <representant>Rinaldi, Massimo</representant>
                                                               <fonctionVille>Chef du Service patrimoine</fonctionVille>
                                                               <fonctionMandat>Administrateur</fonctionMandat>
                                                               <mandatArchive>Actif</mandatArchive>
                                               
                                                               <representant>Surer, Marc-Antoine</representant>
                                                               <fonctionVille>Chef du Service commercial</fonctionVille>
                                                               <fonctionMandat>Administrateur</fonctionMandat>
                                                               <mandatArchive>Actif</mandatArchive>
                                               
                                                               <representant>Balet-Nicolet, Danièle</representant>
                                                               <fonctionVille>Adjointe au Chef de service SFIN</fonctionVille>
                                                               <fonctionMandat>Administratrice</fonctionMandat>
                                                               <mandatArchive>Actif</mandatArchive>
                                                               
                               </mandat>
                </mandats>

et concrètement j’aimerai ceci :

                 <mandats>
                               <mandat>
                                               
                                                               <representant>Pidoux, Jean-Yves</representant>
                                                               <fonctionVille>Conseiller municipal SIL</fonctionVille>
                                                               <fonctionMandat>Président du conseil d'administration</fonctionMandat>
                                                               <mandatArchive>Actif</mandatArchive>
                               </mandat>
                               <mandat>
                                                               <representant>Rinaldi, Massimo</representant>
                                                               <fonctionVille>Chef du Service patrimoine</fonctionVille>
                                                               <fonctionMandat>Administrateur</fonctionMandat>
                                                               <mandatArchive>Actif</mandatArchive>
                               </mandat>
                               <mandat>

                                                               <representant>Surer, Marc-Antoine</representant>
                                                               <fonctionVille>Chef du Service commercial</fonctionVille>
                                                               <fonctionMandat>Administrateur</fonctionMandat>
                                                               <mandatArchive>Actif</mandatArchive>
                               </mandat>
                               <mandat>

                                                               <representant>Balet-Nicolet, Danièle</representant>
                                                               <fonctionVille>Adjointe au Chef de service SFIN</fonctionVille>
                                                               <fonctionMandat>Administratrice</fonctionMandat>
                                                               <mandatArchive>Actif</mandatArchive>
                                                               
                               </mandat>
                </mandats>

est-ce que c’est possible?

Merci d’avance pour votre aide.

Fabrice

Il suffit de mettre les tags <mandat> et </mandat> dans le bloc [BEGIN:...] / [END:...]

PS: merci d’utiliser la syntaxe Markdown dans vos posts et en particulier la syntaxe “Fenced code blocks” pour vos blocs de code (cf. https://www.markdownguide.org/extended-syntax/#fenced-code-blocks) j’ai été obligé d’éditer votre post car en l’état c’était illisible.

Pfff…c’était aussi simple que ça…

Merci !!

C’est tout bon pour ce post.

Dans un template de publication les itérations se font sur l’intégralité de ce qui est dans les blocs BEGIN/END

autre question :
La liste Entite s’affiche avec des tris par défaut sur 3 colonnes. Il se trouve que l’export doit être trié autrement.
est-ce que dans mon code exemple il y a possibilité de demander un tri d’autres colonnes?

Il y a un hook preExport qui permet d’appliquer des règles particulières, par exemple des changement sur les tris par défaut cf. https://docs.simplicite.io/4.0/javadoc/com/simplicite/util/ObjectDB.html#preExport()

Pour changer les ordres de tri faites:

  1. un resetOrders(true) cf.https://docs.simplicite.io/4.0/javadoc/com/simplicite/util/ObjectCore.html#resetOrders(boolean)
  2. les setOrder(n) qui vont bien sur les attributs qui vont bien cf. https://docs.simplicite.io/4.0/javadoc/com/simplicite/util/ObjectField.html#setOrder(int)

Optionnellement faites un resetOrder() à la fin pour restaurer les tris par défaut

Merci, ça marche bien avec l’export natif de Simplicite. Mais il n’y a pas d’effets sur une publication.

Si je passe par une publication :

Code de l’action qui appelle la publication :

	 //Une fonction pour envoyer le contenu xml de l'extract 1 à WSPRINT BDOC pour l'affichage en PDF
	public String envoyerBDOCExtract1(){
		String nomDocument = "listeRepresentants";
		
		AppLog.info(getClass(), " la fonction envoyerBDOCExtract1 a été appelée", null ,  getGrant());
		
		//trier les données
		ObjectDB entite = this.getGrant().getTmpObject("ParticipationEntite");
		this.getField("ParticipationEntiteTypePart").setOrder(1);
		this.getField("participationDirectionLibelle").setOrder(2);
		this.getField("ParticipationEntiteRaison").setOrder(3);

		
		try{
			AppLog.info(getClass(), " fonction envoyerBDOCExtract1 juste avant l'invoke", null ,  getGrant());
			//fait appel à la publication "participationPctExtract1BdocXML" pour construire le xml
			//fillWithCurrentList(this) pour peupler la publication avec la liste des records
			//fillWithCurrentObject(this) pour peupler la publication avec le record courant
			String xml = Tool.toString(getPrintTemplate("participationPctEntiteListeRepresentants").fillWithCurrentList(this) ); // = extract 1 = listeRepresentants
			AppLog.info(getClass(), "xmlExport", "XML = " + xml, getGrant());

			ParticipationBDOCHandler handler = new ParticipationBDOCHandler("listeRepresentants",getGrant());
			//ParticipationBDOCHandler handler = new ParticipationBDOCHandler(getGrant());
			
			AppLog.info(getClass(), "envoyerBDOCExtract1 appel BDOCHANDLER OK", null ,  getGrant());
			
			InputStream in = handler.printWithData2Stream(xml);
			AppLog.info(getClass(), "envoyerBDOCExtract1 step 3 " + (in != null ? "Stream OK " + IOUtils.toString(in, "UTF-8") : " Stream KOOOO"), null ,  getGrant());

			return in!= null ? IOUtils.toString(in, "UTF-8") : null;
		}catch(Exception e ){
			AppLog.error(getClass(),"envoyerBDOCExtract1" ,"Exception lors de la génération de fichier xml listeRepresentants", e, getGrant());
		}

		return null;
	}

Je ne comprends pas ce que vous faites, une publication “visible” se matérialise par un bouton (sur les la liste et/ou chaque item de liste et/ou formulaire

Il n’y a pas besoin d’implémenter une action (ou alors il y a une subtilité qui m’échappe)

Il y a plusieurs exemples sur la démo:

Sur les items de liste:


Sur le formulaire:

Sur la liste:

L’action est là pour :

  1. construire le XML à l’aide de la publication

  2. Envoyer le XML à un webservice

OK compris.

Déjà il manque à priori dans votre code c’est un search (non paginé) explicite (et donc déterministe), en effet si vous appelez fillWithCurrentList cela popule votre template de publication avec le résultat du dernier search (la “current list” de l’instance d’objet), en fonction du contexte d’appel de votre action ça ne contient donc pas forcément tous les records que vous souhaitez publier et ça n’applique pas les éventuels changements de définition que vous avez pu faire depuis le dernier search (filtres, ordre de tri, ordre d’affichage, …)

Personnellement pour éviter les effets de bords quand j’appelle une publication de manière programmatique (dans une action ou autre) je travaille avec une instance d’objet distincte de l’instance courante (this) genre l’instance “temporaire” getGrant().getTmpObject(getName()). Cela permet notamment de ne pas altérer l’instance courante si vous changez les filtres et/ou les ordres de tris et/ou les ordres d’affichage, etc.

J’ai déclaré une instance temporaire pour les tris…ça marche MERCI.

ma publication parcourt également les enregistrements liés de la table mandat à l’aide d’un BEGIN/END

Un peu de la même manière que je filtre les éléments de la table principale Entité, est-ce que je peux filtrer les éléments liés qui feront partie de la publication?

Par exemple pour chaque entité, j’aimerai obtenir seulement les mandats “archivé”

Non le tag [BEGIN:] des templates de publication ne permet pas de spécifier des filtres additionnels (il positionne uniquement un filtre sur la foreign key).

Pour mettre en place des règles de publication plus subtiles il faut passer à une méthode de publication plutôt qu’un simple template de publication

Cela dit vous pouvez aussi spécialiser des objets pour le publication en mettant les filtres statiques (search sepc) qui vont bien sur ces objets, ex: A = objet sans filtre statique, A1 hérite de A avec un filtre sur l’état X, A2 hérite de A avec un filtre statique sur les états Y ou Z, etc. Ensuite dans votre template de publication vous utilisez pas A mais A1 ou A2. Personnellement je trouve que c’est un peu se compliquer la vie vs écrire un peu de code.

PS: je vais quand même regarder quels seraient les impacts d’ajouter des filtres additionnels simples dans la syntaxe du [BEGIN:]

Rectification :

En relisant le code - écrit il y a très longtemps - je vois qu’on peut déjà mettre des filtres avec une syntaxe [BEGIN:<obj name>:<fk field name>:<optional filters>]<filters> est de la forme <field name 1><operator><filter value>,<field name 2><operator><filter value>, ... avec <operator> valant = ou in ou not in, etc.

Nickel… ça va répondre à pas mal de mes besoins :-)

Je me suis précipité pour essayer, mais clairement, je bute sur la syntaxe :

[BEGIN:ParticipationMandat:ParticipationMandat_ParticipationEntite_fk:participationMandatArchive IN 'Archive']

ou

[BEGIN:ParticipationMandat:ParticipationMandat_ParticipationEntite_fk:participationMandatArchive IN "Archive"]

Dans votre cas je mettrais participationMandatArchive=Archive (NB: si on parle d’un attribut énuméré la valeur Archive est bien le code, pas la valeur traduite). Le in c’est pour des valeurs multiples (avec une syntaxe du genre in ('A', 'B', 'C').

Je ne connais pas trop ce mécanisme, je ne suis peut être pas du meilleur conseil sur ce point. Personnellement dès qu’un besoin de publication ça sort de simples itérations sur les objets liés j’écris une methode…

C’est extra avec cette syntaxe et ça couvre une bonne partie des besoins de publication.

le point non couvert c’est le fait de parcourir des objets liés et de ne remonter que les x premiers dans la publication.
Sur ce point je pense que la méthode sera nécessaire. Est-ce que par hasard vous auriez un exemple d’une de vos méthodes que vous pourriez partager?

Non “les N premiers” n’est pas une notion gérable dans un template de publication, ce n’est pas un filtre c’est une notion de pagination.

Pour ce genre de besoins vous devrez écrire votre publication sous forme de code en faisant un search paginé avec une taille de page à N

Est-ce que vous avez un exemple de code?

Une méthode de publication retourne simplement le résultat de la publication. Dans le cas d’un résultat XML c’est un String, ex:

public String myPublicationMethod() {
    StringBuilder xml = new StringBuilder(XMLTool.XML_HEADER);
    ....
    return xml.toString();
}

Le reste c’est de la manipulation standard d’objets (setFilters/search/etc.)

D’autres exemples de methodes de publication (en Rhino mais facilement ransposables en Java) ici: https://docs.simplicite.io/documentation/01-core/publication-examples.md

Je suis navré d’insister mais je ne suis pas à l’aise pour cette méthode.

quelque chose comme ceci ?

	 public String myPublicationMethod() {
	 	AppLog.info(getClass(), " myPublicationMethod  " , null ,  getGrant());
	    
	    StringBuilder xml = new StringBuilder(XMLTool.XML_HEADER);
		ObjectDB o = getGrant().getTmpObject("ParticipationRepresentant ");
		o.resetFilters();
		// Same as above regarding filters
		
		for (String[] row : o.search()) {
		    o.setValues(row);
		    String val = o.getField("participationReprNom").getValue();
			xml.append("<Nom>").append("<Value>"+val+"</Value>");
			xml.append("</Nom>");
		}	
	    return xml.toString();

	}