2010-04-29 5 views
5

Salutations!La fonction document XSLT renvoie le résultat vide sur Maven POM

Je souhaite extraire certaines propriétés de différents POM Maven dans un XSLT via la fonction de document. Le script lui-même fonctionne bien mais la fonction document renvoie un résultat vide pour le POM tant que j'ai le xmlns = "http://maven.apache.org/POM/4.0.0" dans la balise de projet. Si je l'enlève, tout fonctionne bien.

Une idée comment faire ce travail tout en laissant l'attribut xmlns où il appartient ou pourquoi cela ne fonctionne pas avec l'attribut en place?

vient ici la partie pertinente de mon XSLT:

<xsl:template match="abcs"> 
<xsl:variable name="artifactCoordinate" select="abc"/> 
    <xsl:choose> 
     <xsl:when test="document(concat($artifactCoordinate,'-pom.xml'))"> 
     <abc> 
      <ID><xsl:value-of select="$artifactCoordinate"/></ID> 
    <xsl:copy-of select="document(concat($artifactCoordinate,'-pom.xml'))/project/properties"/> 
    </abc> 
     </xsl:when> 
      <xsl:otherwise> 
     <xsl:message terminate="yes"> 
      Transformation failed: POM "<xsl:value-of select="concat($artifactCoordinate,'-pom.xml')"/>" doesn't exist. 
     </xsl:message> 
     </xsl:otherwise> 

</xsl:choose> 

Et, pour être complet, un extrait de POM avec l'attribut "mauvais":

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
<modelVersion>4.0.0</modelVersion> 
<!-- ... --> 
<properties> 
    <proalpha.version>[5.2a]</proalpha.version> 
    <proalpha.openedge.version>[10.1B]</proalpha.openedge.version> 
    <proalpha.optimierer.version>[1.1]</proalpha.optimierer.version> 
    <proalpha.sonic.version>[7.6.1]</proalpha.sonic.version> 
</properties> 
</project> 
+0

Bonne question (+1). Voir ma réponse pour une explication du problème et pour la solution la plus souvent utilisée. :) –

Répondre

10

Votre problème est que l'extrait POM utilise l'espace de noms par défaut. Cela signifie que les éléments, bien que non préfixés, se trouvent dans le "http://maven.apache.org/POM/4.0.0" et non dans le "no namespace".

Cependant, dans cette expression XPath, dans le code XSLT:

document(concat($artifactCoordinate,'-pom.xml'))/project/properties 

les noms project et properties sont sans préfixe. XPath traite toujours les noms non préfixés comme appartenant à "aucun espace de noms". Par conséquent, aucun élément de ce type n'est trouvé et aucun nœud n'est sélectionné.

Solution: Ajouter une définition d'espace de noms à votre <xsl:stylesheet>, permet de dire:

xmlns:p="http://maven.apache.org/POM/4.0.0" 

réécrire les noms d'éléments dans les expressions faisant référence à des noeuds de POM de someElement à p:someElement. Par exemple:

document(concat($artifactCoordinate,'-pom.xml'))/p:project/p:properties 
+0

Merci Dimitre - cela fonctionne! En ce moment cette solution me donne xmlns: pom = "..." dans chaque élément que je reçois de l'appel de fonction de document mais j'espère trouver un moyen de se débarrasser de cela, peut-être en fournissant la déclaration dans le document cible avant. – Jan

+0

@Jan: Il suffit d'ajouter '' l'attribut suivant: 'exclude-result-prefixes =" pom "' –

+0

Ah! C'est une belle addition - merci. J'ai également trouvé une solution générale qui est utile pour mon besoin particulier (voir ma réponse). – Jan

3

Ceci est un espace de noms problème. Le xmlns="http://maven.apache.org/POM/4.0.0" dans le document source signifie que tous les éléments sont par défaut placés dans l'espace de noms "http://maven.apache.org/POM/4.0.0" dans le document XML. Si vous voulez en obtenir un compte dans votre xslt, vous devez déclarer cet espace de noms dans votre xslt (avec ou sans préfixe à utiliser), puis utiliser cet espace de noms lors de la sélection de vos éléments. Par exemple, je devine que le modèle dans votre exemple est destiné à correspondre à un élément "abcs" dans votre POM, oui? Essayez d'ajouter une déclaration d'espace de noms dans votre xsl: stylesheet, .: par exemple

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:pom="http://maven.apache.org/POM/4.0.0" version="1.0"> 

qui dit à l'XSL « Je veux ajouter « pom » comme préfixe qui identifie l'espace de noms « http://maven.apache.org/POM/4.0.0 » dans ce document. »

Ensuite, lors de la sélection des éléments ou des modèles correspondants, utilisez ce préfixe, par exemple:

<xsl:template match="pom:abcs"> 

Ou essayez sans les préfixes en déclarant votre feuille de style avec l'espace de noms POM par défaut, quelque chose comme:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns="http://maven.apache.org/POM/4.0.0" version="1.0"> 
+0

Merci! Malheureusement, "l'approche globale" ne fonctionne pas pour moi - apparemment parce que j'ai aussi des tags d'autres espaces de noms. Peut-être que ma question n'était pas assez précise - les abcs sont dans un autre espace de noms. L'approche par préfixe fonctionne pour moi bien, comme Dimitre suggéré ci-dessous. – Jan

+0

@Matt: Si vous voulez un espace de nommage par défaut lors de la sélection d'éléments avec XPath, vous devez utiliser 'xpath-default-namespace' (pris en charge dans XSLT 2.0 ou version ultérieure), comme décrit dans http://www.w3.org/TR/xslt20/# unprefixed-qnames. La définition de l'espace de nom par défaut avec 'xmlns =" ​​... "' ne configure que l'espace de noms par défaut des littéraux XML dans la feuille de style, les expressions XPath ne sont pas affectées. – markusk

+0

@markusk Merci pour la clarification; Je n'ai pas encore utilisé l'espace de noms xpath-default-name, bien sûr que ça me sera utile à un moment donné dans mon futur! –

1

Node peut (si vous utilisez XSLT 2.0+) être aussi par * parce adressé qu'ils se trouvent dans un autre espace de noms.

<xsl:copy-of select="document(concat($artifactCoordinate,'-pom.xml'))/*:project/*:properties)"/> 

Cela peut être juste pratique ou particulièrement utile si l'espace de noms est inconnu. Dans ce cas, le bon effet secondaire est que si l'espace de noms est marqué de cette façon, les nœuds de l'autre espace de nom ne reçoivent pas d'annotation - ce qui n'est pas voulu dans notre cas.

+1

@Jan: La syntaxe '*: name' est prise en charge uniquement dans XPath 2.0. –

+0

@Jan: Notez également que vous pouvez utiliser 'xpath-default-namespace' si vous utilisez XSLT 2.0 ou version ultérieure, comme décrit dans http://www.w3.org/TR/xslt20/#unprefixed-qnames. – markusk

+0

@Dimitre: Bien sûr - désolé, j'ai oublié d'ajouter ce détail (en utilisant cela). – Jan