2011-01-25 18 views
5

hi Ho un documento XML Sitemap che sembra qualcosa di simileXSLT copia dei senza figli

<pagenode title="home" url="~/" fornavbar="true"> 
<pagenode title="admin" url="~/admin" fornavbar="false"> 
    <pagenode title="users" url="~/admin/users" fornavbar="false"/> 
    <pagenode title="events" url="~/admin/events" fornavbar="true"/> 
</pagenode> 
<pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
<pagenode title="contact us" url="~/contactus" fornavbar="false"/> 
</pagenode> 

ora voglio recuperare un documento XML per la barra di navigazione, che include tutti i pagenodes che hanno fornavbar = vero. Come si può fare?

il più vicino sono stato in grado di ottenere fino ad ora è stato questo:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="pagenode[@fornavbar='true']"> 
    <xsl:copy-of select="."/> 
</xsl:template> 
</xsl:stylesheet> 

il problema di questo è che include tutti i figli di qualsiasi cosa abbinate come barra di navigazione

voglio solo copiare tutti gli attributi , non tutti i bambini

ma se provo

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="pagenode[@fornavbar='true']"> 
    <pagenode title="{@title}" url="{@url}"/> 
    <xsl:apply-templates/> 
</xsl:template> 
</xsl:stylesheet> 

poi ho 2 problemi

  1. potrei digitare fuori ogni attributo a parte, e ho un bel po 'per pagina e theyre inclini a cambiare finalmente
  2. perde la gerarchia. tutto diventa piatto uno dopo l'altro

gradirei tutto e qualsiasi aiuto in materia.

grazie!

EDIT: esempio di output che id piace vedere

<pagenode title="home" url="~/" fornavbar="true"> 
<pagenode title="events" url="~/admin/events" fornavbar="true"/> 
<pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
</pagenode> 
+0

Buona domanda, +1. Vedi la mia risposta per una soluzione completa ma molto breve che sfrutta appieno il modello di progettazione XSLT più fondamentale. :) –

risposta

2

è possibile iterare gli attributi di un nodo utilizzando xsl:foreach select="@*" in questo modo non c'è bisogno di copiare gli attributi a mano. se chiami xsl:apply-templates all'interno del tuo elemento pagenode dovresti ottenere il risultato desiderato.

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="pagenode[@fornavbar='true']"> 
     <pagenode> 
      <xsl:for-each select="@*"> 
       <xsl:attribute name="{name(.)}"><xsl:value-of select="."/></xsl:attribute> 
      </xsl:for-each> 
      <xsl:apply-templates/> 
     </pagenode> 
    </xsl:template> 
</xsl:stylesheet> 

rende

<?xml version="1.0"?> 
<pagenode title="home" url="~/" fornavbar="true"> 
    <pagenode title="events" url="~/admin/events" fornavbar="true"/> 
    <pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
</pagenode> 
+1

'' è molto più succinto –

+0

grazie a milioni! funziona esattamente ciò di cui avevo bisogno !!! sei eccellente! –

1

XSLT dovrebbe assomigliare a questa:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="pagenode[@fornavbar='true']"> 
    <pagenode> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates/> 
    </pagenode> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Devono essere gli avanzi del mio test. – akond

+0

+1 Per la correzione più semplice. –

3

Questa è probabilmente la soluzione XSLT più breve e più pura:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="*[@fornavbar = 'false']"> 
    <xsl:apply-templates/> 
</xsl:template> 
</xsl:stylesheet> 

quando tale trasformazione viene applicato sul documento XML fornito:

<pagenode title="home" url="~/" fornavbar="true"> 
    <pagenode title="admin" url="~/admin" fornavbar="false"> 
     <pagenode title="users" url="~/admin/users" fornavbar="false"/> 
     <pagenode title="events" url="~/admin/events" fornavbar="true"/> 
    </pagenode> 
    <pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
    <pagenode title="contact us" url="~/contactus" fornavbar="false"/> 
</pagenode> 

The Wanted, risultato corretto è prodotto:

<pagenode title="home" url="~/" fornavbar="true"> 
    <pagenode title="events" url="~/admin/events" fornavbar="true"/> 
    <pagenode title="catalog" url="~/catalog" fornavbar="true"/> 
</pagenode> 

Spiegazione:

  1. La regola dell'identità (modello) copia ogni nodo "così com'è". Utilizzando il identity rule ed ignorando che è il modello più fondamentale di progettazione XSLT.

  2. c'è un unico modello che sostituisce la regola dell'identità - per gli elementi la cui fornavbar attributo è "false". Qui l'azione specificata è applicare i template ai child dell'elemento corrente.

+1

+1 buona risposta. Solo per la logica semantica e inversa di una sola soluzione di regole, userei '* [non (self :: pagenode/@ fornavbar = 'true')]' –

+0

@ Alejandro: Grazie. Cosa intendi? –

+0

Voglio dire che la regola di bypass corrisponderà a qualsiasi elemento che ha un attributo '@ fornavbar' con valore stringa' 'false'', quindi la regola di identità corrisponderà a ** qualsiasi elemento ** non avendo un attributo' @ fornavbar' con ''false "valore stringa, invece di elementi' pagenode' ** solo ** aventi un attributo '@ fornavbar' con valore stringa' 'true''. –

Problemi correlati