Conditions XPath dans une Logic App

Tanguy SCHOUBERT
Publié par Tanguy SCHOUBERT
Catégorie : Azure / Logic Apps
21/09/2020

Le besoin : récupérer une valeur spécifique dans le Json

 

Notre Logic App reçoit en entrée ce payload Json :

 

{
  "Product": {
    "@type": "food",
    "Names": [
      {
        "@language": "fr",
        "value": "Farine"
      },
      {
        "@language": "en",
        "value": "Flour"
      }
    ]
  }
}

 

Ici nous voulons récupérer le nom du produit dans une langue spécifique. Pour accéder à cette valeur, plusieurs méthodes sont possibles, incluant les suivantes :

  • Boucler sur le tableau des « Names » à l’aide d’un For Each et utiliser la shape Condition sur le champ « @language »
  • Utiliser la shape Filter Array sur le tableau des « Names » avec un critère sur « @language »
  • Utiliser une expression XPath avec une condition sur « @language »

Pour cet exemple très simple, les trois méthodes sont envisageables. Mais pour un cas d’usage plus complexe, il peut être intéressant d’utiliser du XPath afin de ne pas multiplier les shapes.

 

Utilisation de l’expression XPath

 

Pour pouvoir utiliser une expression XPath il nous faut d’abord convertir le payload Json en XML. Si nous essayons tel quel, la Logic App affiche un message d’erreur : un noeud racine XML ne peut pas avoir d’attribut. Pour éviter cela nous encapsulons le noeud racine « Product » dans un nouveau noeud « root ». Dans l’expression Logic App :

 

concat('{"root":', triggerbody(), '}')

 

Le résultat obtenu :

 

{
  "root": {
    "Product": {
      "@type": "food",
      "Names": [
        {
          "@language": "fr",
          "value": "Farine"
        },
        {
          "@language": "en",
          "value": "Flour"
        }
      ]
    }
  }
}

 

Ainsi l’expression XPath complète :

 

xpath(xml(json(concat('{"root":', triggerbody(), '}'))), '/*[name()="root"]/*[name()="Product"]/*[name()="Names" and @language="en"]')

 

Le résultat est sous la forme suivante :

 

[{"$content-type":"application/xml;charset=utf-8","$content":"PE5hbWVzIGxhbmd1YWdlPSJlbiI+DQogIDx2YWx1ZT5GbG91cjwvdmFsdWU+DQo8L05hbWVzPg=="}]

 

Nous avons donc un tableau Json contenant notre résultat dans un champ « $content ». Pour aller récupérer ce résultat :

 

xpath(xml(json(concat('{"root":', triggerbody(), '}'))), '/*[name()="root"]/*[name()="Product"]/*[name()="Names" and @language="en"]')?[0]?['$content']

 

On voit ce résultat en XML car décodé automatiquement à partir du base64 :

 

<Names language="en">
  <value>Flour</value>
</Names>

 

Enfin, pour récupérer la valeur de la balise « value », nous convertissons le résultat en Json après l’avoir décodé explicitement depuis le base64 puis parsé en XML. Notre expression finale :

 

json(xml(decodeBase64(xpath(xml(json(concat('{"root":', triggerbody(), '}'))), '/*[name()="root"]/*[name()="Product"]/*[name()="Names" and @language="en"]')?[0]?['$content'])))?['Names']?['value']

 

Et notre résultat final :

 

Flour

 

Nous arrivons donc à la valeur souhaitée grâce à notre expression – certes un peu complexe. Pour plus de lisibilité il est tout à fait possible de la décomposer en utilisant par exemple des variables dans notre Logic App, surtout s’il y a plusieurs conditions à appliquer.