Question

Je ne suis pas sûr que ce soit possible, car je suis très novice en XSLT, mais peut-être que certains d'entre vous pourraient m'aider ici? C'est un peu délicat et je n'ai rien trouvé de tel sur Internet:

Le problème est que j’ai un fichier XML d’entrée avec les espaces de noms déclarés et tous et que je n’ai qu’à le modifier légèrement (en ajoutant ou en supprimant des attributs, ou en les déplaçant vers d’autres emplacements). Mais en même temps, je dois mettre à jour les références d'espace de noms dans la balise de document du document. Ainsi, par exemple, le XML d'entrée peut ressembler à ceci:

<order
  xmlns="some.url.01"
  xmlns:ns2="some.other.url"
  xmlns:ns3="another.one"
>
  <orderEntry>
    <orderControl>
      <mandant>test</mandant>
      <businessUnit>test</businessUnit>
      <inboundChannel>test</inboundChannel>
      <timestamp>timestamp</timestamp>
      <requestedDocuments>
        <ns2:document>orderForm</ns2:document>
      </requestedDocuments>
    </orderControl>
  </orderEntry>
</order>

le XML résultant devrait ressembler à ceci:

<order
  xmlns="some.url.02"
  xmlns:ns2="some.other.url.02"
  xmlns:ns3="another.one.02"
>
  <orderEntry>
    <orderControl>
      <mandant>test</mandant>
      <businessUnit>test</businessUnit>
      <inboundChannel>test</inboundChannel>
      <!-- deleted timestamp for example -->
      <requestedDocuments>
        <ns2:document>orderForm</ns2:document>
      </requestedDocuments>
    </orderControl>
  </orderEntry>
</order>

mais la seule chose que je reçois est:

<order
  xmlns="some.url.02"
>
  <orderEntry>
    <orderControl>
      <mandant>test</mandant>
      <businessUnit>test</businessUnit>
      <inboundChannel>test</inboundChannel>
      <!-- deleted timestamp for example -->
      <requestedDocuments>
        <ns2:document xmlns:ns2="some.other.url.02">orderForm</ns2:document>
      </requestedDocuments>
    </orderControl>
  </orderEntry>
</order>

Maintenant, peut-être que pour un ou deux d'entre vous, ce n'est peut-être pas si grave, mais j'ai la restriction voulant que le document de sortie soit identique à celui du document de départ, à l'exception des modifications demandées (modifications apportées à l'espace de noms et suppression).

Mon XSLT ressemble à ceci:

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="some.url.02"
  xmlns:ns2="some.other.url.02"
  xmlns:ns3="another.one.02"
>
  <xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>

  <xsl:strip-space elements="*"/>

  <xsl:template match="*">
    <xsl:choose>
      <xsl:when test="name(.) != 'timestamp'">
        <xsl:element name="{node-name(.)}">
          <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:attribute name="{node-name(.)}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

Quelqu'un peut-il aider s'il vous plaît? Les espaces de noms sont délicats: (

P.S .: Celui qui a édité mon entrée: Merci:)

Était-ce utile?

La solution

Vous pouvez définir l'espace de nom sur l'élément de sortie avec l'attribut d'espace de nom:

<xsl:element name="{node-name(.)}" namespace="http://www.bar.org">
  // ...
</xsl:element>

Notez que l'espace de nom doit être un URI et bien que je suppose que vous le sachiez, c'est probablement une bonne idée d'utiliser des URI dans votre exemple.

Voici un lien vers l'excellent tutoriel ZVON qui contient des exemples concrets: html

Je conviens que les espaces de noms sont délicats. Comme vous le savez, le préfixe est sémantiquement sans importance, mais de nombreux systèmes vous permettent de choisir votre préfixe pour des raisons esthétiques. Consultez également Saxon ( http://saxon.sourceforge.net/ )

MODIFIER Je pense que vous trouverez votre réponse ici: Espace de nom de balise racine XSLT au lieu de l'espace de nom d'attribut d'élément

Autres conseils

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ns1_src="some.url.01"
  xmlns:ns2_src="some.other.url"
  xmlns:ns3_src="another.one"
  xmlns="some.url.02"
  xmlns:ns2="some.other.url.02"
  xmlns:ns3="another.one.02"
>
  <!-- 
    Note that all the source namespaces got their own new "*_src" prefix. 
    The target namespaces take over the original prefixes. 
    "some.url.02" is the new global namespace.
  -->

  <xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- the identity template to copy everything, unless 
       it has been declared otherwise -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <!-- three templates to handle elements -->
  <xsl:template match="ns1_src:*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="node() | @*" />
    </xsl:element>
  </xsl:template>

  <xsl:template match="ns2_src:*">
    <xsl:element name="ns2:{local-name()}">
      <xsl:apply-templates select="node() | @*" />
    </xsl:element>
  </xsl:template>

  <xsl:template match="ns3_src:*">
    <xsl:element name="ns3:{local-name()}">
      <xsl:apply-templates select="node() | @*" />
    </xsl:element>
  </xsl:template>

  <!-- three templates to handle attributes -->
  <xsl:template match="@ns1_src:*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="@ns2_src:*">
    <xsl:attribute name="ns2:{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="@ns3_src:*">
    <xsl:attribute name="ns3:{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>

  <!-- timestamps will be ignored -->
  <xsl:template match="ns1_src:timestamp" />

</xsl:stylesheet>

Sortie:

<order xmlns="some.url.02">
  <orderEntry>
    <orderControl>
      <mandant>test</mandant>
      <businessUnit>test</businessUnit>
      <inboundChannel>test</inboundChannel>
      <requestedDocuments>
        <ns2:document xmlns:ns2="some.other.url.02">orderForm</ns2:document>
      </requestedDocuments>
    </orderControl>
  </orderEntry>
</order>
<xsl:template match="a:*">
  <xsl:element name="{local-name()}"
               namespace="http://example.com/B">
    <xsl:copy-of select="@*" />
    <xsl:apply-templates />
  </xsl:element>
</xsl:template>

Il recherche tous les éléments de l'espace de noms avec le préfixe a et les remplace par un élément portant le même nom d'espace de nom http://example.com/B . Tous les attributs sont copiés "tels quels", puis tous les enfants sont évalués.

Ajoutez votre traitement personnalisé dans ou autour de celui-ci selon vos besoins.

Utilisez-vous la tâche XSLT d'Ant pour effectuer votre transformation?

Si la réponse est oui, vous pouvez passer du moteur XSLT par défaut fourni avec Sun JDK 1.5+. Lisez this .

Lisez également cet article sur les espaces de noms dans XSLT

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top