0
votes

XSLT: Convertir XML en JSON Création d'un groupe de sous-nœuds

Cela fait des jours d'essayer d'effectuer une transformation pour obtenir un fichier JSON à partir de documents XML. Mon XML Doc a différents niveaux de sous-nœuds, tous les exemples que j'ai trouvés sur Internet n'atteignent pas mon cas. Voici mon exemple XML: xxx

JSON souhaité: xxx

signifie chaque fois que je n'ai pas imbriqué Éléments, les éléments enfants sont regroupés avec l'élément parent, et ainsi de suite.

J'ai essayé du code XSL ( See1 et See2 ) et n'a pas pu les faire travailler pour mon cas.


3 commentaires

"Tous les exemples que j'ai trouvés sur Internet ne captent pas mon cas" - la programmation n'est pas simplement une question de trouver un exemple sur Internet qui correspond à votre cas. Vous devez comprendre les concepts afin que vous puissiez adapter les exemples à votre cas.


Le "JSON souhaité" n'est pas du tout JSON, exécutez-le par JSONLINT.COM et cela vous dira qu'avoir divers A clés n'est pas autorisé.


Aussi, quelles sont toutes les virgules dans les balises de démarrage des éléments tels que ? Ce n'est même pas un XML bien formé.


3 Réponses :


0
votes
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="root">
        <xsl:text>{</xsl:text>
        <xsl:apply-templates select="//foo"/>
        <xsl:text>}</xsl:text>
    </xsl:template>
    <xsl:template match="//foo">
        <xsl:choose>
            <xsl:when test=" count(ancestor::foo) = 1 and child::foo"/>
            <xsl:when test="foo[child::foo]"/>
            <xsl:otherwise>
                <xsl:text>&quot;</xsl:text><xsl:value-of select="@group"/><xsl:text>&quot;</xsl:text>:<xsl:text> {&#x0A;</xsl:text>
                <xsl:text>      &quot;</xsl:text><xsl:value-of select="@id/name()"/><xsl:text>&quot;</xsl:text>:<xsl:value-of select=" concat(' ',@id)"/>
                <xsl:text>&#x0A; },</xsl:text>
            </xsl:otherwise>
        </xsl:choose>     
    </xsl:template>    
</xsl:stylesheet>

0 commentaires

0
votes

Veuillez vérifier ce code: xxx


0 commentaires

0
votes

Il n'est pas tout à fait évident que vous voulez que vous souhaitiez que le "JSON" souhaité a des propriétés dupliquées si il y a divers éléments FOO Group = "a" code> éléments mais en général de XML à la génération JSON que vous pouvez utiliser XSLT 3 avec prise en charge des cartes XPath 3.1 ( HTTPS: //www.w3.org/tr/xpath-31/#id-maps-and-Ardrares ) et la méthode code> JSON code> ou le xml-to-json Fonction ( https://www.w3.org/tr/xslt- 30 / # JSON , https: // www.w3.org/tr/xslt-30/#func-xml-to-json ), de cette façon, vous avez deux façons de créer JSON et de la sortie, vous pouvez également transformer votre XML directement sur XPATH 3.1 Maps / les matrices et les sérialiser avec code> ou vous pouvez utiliser le traitement XSLT habituel pour transformer votre entrée XML à La représentation XML JSON La fonction XML-To-JSON CODE> s'attend et appliquez-la pour obtenir le JSON comme texte.

Voici un exemple de la première approche: p>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="#all"
    xmlns="http://www.w3.org/2005/xpath-functions"
    expand-text="yes"
    version="3.0">

  <xsl:mode on-no-match="shallow-skip"/>
  <xsl:strip-space elements="*"/>

  <xsl:output method="text"/>

  <xsl:variable name="json-xml">
      <xsl:apply-templates/>
  </xsl:variable>

  <xsl:template match="/">
      <xsl:sequence select="xml-to-json($json-xml, map { 'indent' : true() })"/>
  </xsl:template>

  <xsl:template match="*[*]">
      <map>
          <xsl:for-each-group select="foo" group-by="string(@group)">
              <xsl:choose>
                  <xsl:when test="not(tail(current-group()))">
                      <map key="{current-grouping-key()}">
                          <string key="id">{@id}</string>
                      </map>
                  </xsl:when>
                  <xsl:otherwise>
                      <array key="{current-grouping-key()}">
                          <xsl:apply-templates select="current-group()"/>
                      </array>
                  </xsl:otherwise>
              </xsl:choose>
          </xsl:for-each-group>          
      </map>
  </xsl:template>

  <xsl:template match="*[not(*)]">
      <map>
          <string key="id">{@id}</string>
      </map>
  </xsl:template>

</xsl:stylesheet>


4 commentaires

Merci @Martin ne savait pas à propos de cette approche. Un problème lorsque j'exécute votre code pour un gros fichier, la sortie n'est pas dans le bon ordre.


La deuxième approche avec XML-TO-JSON doit conserver la commande à partir de l'original XML. Malheureusement, la première approche qui crée des cartes XPath n'est pas capable d'assurer la commande car les éléments d'une carte XPath n'ont pas de commande.


Pouvez-vous poster un doc sur les instructions que vous avez utilisées, je veux aller au fond des détails. Merci d'avance


@MCHAHOUD, j'ai ajouté des liens vers les sections spécifiques correspondantes.