2010-02-12 12 views
12

Vorrei aggiungere un elemento a un documento xml e vorrei passare come parametro il percorso dell'elemento. file diCome utilizzare un parametro in xslt come XPath?

sample.xml:

<?xml version="1.0"?> 
<stuff> 
    <element1> 
    <foo>2</foo> 
<bar/> 
    </element1> 
    <element2> 
<subelement/> 
<bar/> 
    </element2> 
    <element1> 
    <foo/> 
<bar/> 
    </element1> 
</stuff> 

Usando:

xalan.exe -p myparam "element1" sample.xml addelement.xslt 

vorrei il seguente risultato:

<?xml version="1.0"?> 
<stuff> 
    <element1> 
    <foo>2</foo> 
    <bar/> 
    <addedElement/> 
    </element1> 
    <element2> 
<subelement/> 
<bar/> 
    </element2> 
    <element1> 
    <foo/> 
<bar/> 
    <addedElement/> 
    </element1> 
</stuff> 

ho riesce a scrivere addelement.xslt, quando hardcoding il percorso funziona, ma quando provo a usare il parametro myparam nell'attributo match ottengo:

XPathParserException: A node test was expected. 
pattern = '$myparam/*[last()]' Remaining tokens are: ('$' 'myparam' '/' '*' '[' 'last' '(' ')' ']') (addelement.xslt, line 12, column 42) 

addelement.xslt

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="element1/*[last()]"> 
    <xsl:copy-of select="."/> 
<addedElement></addedElement> 
</xsl:template> 

</xsl:stylesheet> 

addelement.xslt con il percorso hardcoded sostituito

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:param name="myparam"/> 

<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="$myparam/*[last()]"> 
    <xsl:copy-of select="."/> 
<addedElement></addedElement> 
</xsl:template> 

</xsl:stylesheet> 

Grazie per l'aiuto

risposta

6

Non credo che è possibile utilizzare le variabili/paramaters a modelli corrispondenti come hai codificato. Anche questo non funziona

<xsl:template match="*[name()=$myparam]/*[last()]"> 

Invece, provare a cambiare il primo modello di corrispondenza per come segue, in modo che il controllo dei parametri si trova all'interno del codice del template, non come parte della dichiarazione partita.

<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     <xsl:if test="local-name() = $myparam"> 
      <addedElement/> 
     </xsl:if> 
    </xsl:copy> 
</xsl:template> 
+0

vuoi dire che variabili/parametri non sono un'espressione XPath valida? Tuttavia, non riesco a farlo funzionare con la soluzione. – David

+3

Prima di tutto, XSLT 1.0 non consente affatto l'uso di variabili/parametri nei modelli di corrispondenza. XSLT 2.0 lo consente ma se si utilizza Xalan, un processore XSLT 1.0, non è possibile utilizzare le funzionalità XSLT 2.0. In secondo luogo, se si dispone di una variabile o un parametro di tipo stringa con un nome di elemento, non è possibile utilizzarlo per costruire espressioni XPath con esso dinamicamente. Non è così che funzionano i parametri/variabili, né in XPath né in altre lingue. Se il valore della variabile/parametro è di tipo string, puoi utilizzarlo ovunque sia consentita una stringa, come ha fatto Tim. –

+0

Grazie Martin, conosci qualche processore XSLT 2.0 basato su riga di comando? – David

1

Ecco come si potrebbe fare con XSLT 1.0:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:param name="n" select="'element1'"/> 

<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*/*[last()]"> 
    <xsl:choose> 
    <xsl:when test="local-name(..) = $n"> 
     <xsl:copy-of select="."/> 
     <addedElement></addedElement> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

</xsl:stylesheet> 
Problemi correlati