2010-04-29 19 views
5

Saluti!La funzione documento XSLT restituisce risultati vuoti su Maven POM

Desidero estrarre alcune proprietà da diverse POM Maven in un XSLT tramite la funzione documento. Lo script funziona correttamente ma la funzione del documento restituisce un risultato vuoto per il POM finché ho il xmlns = "http://maven.apache.org/POM/4.0.0" nel tag del progetto. Se lo rimuovo, tutto funziona bene.

Qualche idea su come eseguire questa operazione lasciando l'attributo xmlns a cui appartiene o perché non funziona con l'attributo in posizione?

Arriva la quota di competenza del mio 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> 

E, per completezza, un estratto POM con l'attributo "cattivo":

<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

Buona domanda (+1). Vedi la mia risposta per una spiegazione del problema e per la soluzione più utilizzata. :) –

risposta

10

Il tuo problema è che l'estratto POM utilizza lo spazio dei nomi predefinito. Ciò significa che gli elementi, sebbene non prefissati, si trovano nello "http://maven.apache.org/POM/4.0.0" - non nel "nessun spazio dei nomi".

Tuttavia, in questa espressione XPath, nel codice XSLT:

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

i nomi project e properties sono senza prefisso. XPath considera sempre i nomi non prefissati come appartenenti a "nessun spazio dei nomi". Quindi, non vengono trovati tali elementi e nessun nodo è selezionato.

Soluzione: aggiungere una definizione dello spazio dei nomi per il vostro <xsl:stylesheet>, consente di dire:

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

quindi riscrivere i nomi degli elementi in qualsiasi espressioni che fanno riferimento i nodi POM da someElement a p:someElement. Ad esempio:

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

Grazie Dimitre - funziona! In questo momento questa soluzione mi dà xmlns: pom = "..." in ogni elemento che ottengo dalla chiamata di funzione del documento, ma spero di trovare un modo per sbarazzartene, magari fornendo la dichiarazione nel documento di destinazione in precedenza. – Jan

+0

@Jan: Basta aggiungere al '' il seguente attributo: 'exclude-result-prefixes =" pom "' –

+0

Ah! Questa è una bella aggiunta - grazie. Ho anche trovato una soluzione generale che è utile per il mio bisogno speciale (vedi la mia risposta). – Jan

3

Questo è uno spazio dei nomi problema. Lo xmlns="http://maven.apache.org/POM/4.0.0" nel documento di origine indica che tutti gli elementi sono impostati per impostazione predefinita nello spazio dei nomi "http://maven.apache.org/POM/4.0.0" nel documento XML.

Se si desidera ottenerli nel proprio xslt, è necessario dichiarare tale spazio dei nomi in xslt (con o senza prefisso da utilizzare) e quindi utilizzare tale spazio dei nomi quando si selezionano gli elementi.

Ad esempio, suppongo che il modello dell'esempio corrisponda a un elemento "abcs" nel tuo POM, sì? Prova ad aggiungere una dichiarazione dello spazio dei nomi nella vostra xsl: "Voglio aggiungere 'pom' come prefisso che identifica il namespace 'http://maven.apache.org/POM/4.0.0' in questo documento" foglio di stile, per es .:

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

che dice di XSL

Poi, quando la selezione di elementi o corrispondenti modelli, utilizzare tale prefisso, ad esempio:

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

O provare senza i prefissi dichiarando il vostro foglio di stile con lo spazio dei nomi POM come predefinito, qualcosa di simile a:

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

Grazie! Purtroppo l'"approccio globale" non funziona per me, apparentemente perché ho tag anche da altri namespace. Forse la mia domanda non era abbastanza precisa: gli abc si trovano in un altro spazio dei nomi. L'approccio per prefisso funziona anche per me, come suggerito da Dimitre di seguito. – Jan

+0

@Matt: se si desidera uno spazio dei nomi predefinito quando si selezionano gli elementi con XPath, è necessario utilizzare 'xpath-default-namespace' (supportato in XSLT 2.0 o successivo), come descritto in http://www.w3.org/TR/xslt20/# senza prefisso-QNames. L'impostazione dello spazio dei nomi predefinito con 'xmlns =" ​​... "' configura solo lo spazio dei nomi predefinito dei valori letterali XML nel foglio di stile, le espressioni XPath non sono influenzate. – markusk

+0

@markusk Grazie per il chiarimento; Non ho ancora usato xpath-default-namespace, certo che sarà utile ad un certo punto nel mio futuro! –

1

nodo può (se si utilizza XSLT 2.0 +) anche essere indirizzato tramite * perché si trovano in un altro spazio.

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

Questo può essere conveniente o particolarmente utile se il namespace è sconosciuto. In questo caso, l'effetto collaterale è che se lo spazio dei nomi è marcato in questo modo, i nodi dell'altro spazio dei nomi non ricevono un'annotazione, che nel nostro caso non è richiesta.

+1

@ Jan: la sintassi '*: name' è supportata solo in XPath 2.0. –

+0

@ Jan: Si noti inoltre che è possibile utilizzare 'xpath-default-namespace' se si utilizza XSLT 2.0 o versione successiva, come descritto in http://www.w3.org/TR/xslt20/#unprefixed-qnames. – markusk

+0

@Dimitre: Certo, scusate, ho dimenticato di aggiungere quel dettaglio (usando quello). – Jan

Problemi correlati