2011-02-28 4 views
2

fait une recherche pour cela et n'a pas trouvé de réponse, donc ici ...XSLT: faire un nœud enfant un frère du noeud contextuel

J'ai quelques xml semblable à ce qui suit:

<?xml version="1.0" encoding="utf-8"?> 
<footnote ref="1"> 
    <para>Here is some text about some guy who made 
     <emphasis role="italic">fascinating</emphasis> comment I want to quote 
     <blockquote> So I went to this place and met this guy....</blockquote> 
     It seemed more interesting at the time. 
    </para> 
</footnote> 

Je veux utiliser xslt changer à un nouveau schéma (à l'aide nouveau préfixe d'espace de noms)

<?xml version="1.0" encoding="utf-8"?> 
<nns:footnote ref="1"> 
    <nns:fn-para>Here is some text about some guy who made 
     <nns:emph type="it">fascinating</nns:emph> comment I want to quote: 
    </nns:fn-para> 
    <nns:fn-blockquote> 
     <nns:bq-para>So I went to this place and met this guy....</nns:bq-para> 
    </nns:fn-blockquote> 
    <nns:fn-para> It seemed more interesting at the time.</nns:fn-para> 
</nns:footnote> 

J'ai essayé quelques petites choses ... prendre un para qui est un descendant de la note et une boucle à travers les enfants, mais c'est difficile matic parce que ce n'est pas seulement des nœuds de texte dans le para, il y a aussi des tags emph, et je ne sais toujours pas comment placer un nœud enfant dans l'arbre et dans l'arbre des résultats ... une biche qui a du sens?

Répondre

3

EDIT: petit refactor et explication étendue.

Cette feuille de style:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:nns="nns"> 
    <xsl:key name="kNodeByPrecedingBlock" 
      match="para/node()[not(self::blockquote)]" 
      use="generate-id(
        (..|preceding-sibling::*[self::blockquote][1])[last()] 
       )"/> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="footnote"> 
     <nns:footnote> 
      <xsl:apply-templates select="node()|@*"/> 
     </nns:footnote> 
    </xsl:template> 
    <xsl:template match="para"> 
     <xsl:apply-templates select=".|blockquote" mode="group"/> 
    </xsl:template> 
    <xsl:template match="emphasis"> 
     <nns:emph> 
      <xsl:apply-templates select="node()|@*"/> 
     </nns:emph> 
    </xsl:template> 
    <xsl:template match="emphasis/@role"> 
     <xsl:attribute name="type"> 
      <xsl:value-of select="substring(.,1,2)"/> 
     </xsl:attribute> 
    </xsl:template> 
    <xsl:template match="blockquote"> 
     <nns:fn-blockquote> 
      <nns:bq-para> 
       <xsl:apply-templates/> 
      </nns:bq-para> 
     </nns:fn-blockquote> 
    </xsl:template> 
    <xsl:template match="para" mode="group" name="makePara"> 
     <xsl:variable name="vGroup" 
      select="key('kNodeByPrecedingBlock',generate-id())"/> 
     <xsl:if test="$vGroup"> 
      <nns:fn-para> 
       <xsl:apply-templates select="$vGroup"/> 
      </nns:fn-para> 
     </xsl:if> 
    </xsl:template> 
    <xsl:template match="*" mode="group"> 
     <xsl:apply-templates select="."/> 
     <xsl:call-template name="makePara"/> 
    </xsl:template> 
</xsl:stylesheet> 

Sortie:

<nns:footnote ref="1" xmlns:nns="nns"> 
    <nns:fn-para>Here is some text about some guy who made 
     <nns:emph type="it">fascinating</nns:emph> comment I want to quote 
    </nns:fn-para> 
    <nns:fn-blockquote> 
     <nns:bq-para> So I went to this place and met this guy....</nns:bq-para> 
    </nns:fn-blockquote> 
    <nns:fn-para>   It seemed more interesting at the time. 
    </nns:fn-para> 
</nns:footnote> 

Remarque: règle d'identité pour écraser (juste pour le style, mais il est un bon modèle). Quatre règles de transformation directe correspondant footnote, emphasis, @role attribut de emphasis et . Regroupement des clés "en ligne" para enfants: l'identifiant de génération du premier élément "block" précédent ou le parent para. Règle de regroupement pour para appliquant des gabarits aux éléments auto et "bloqués" en mode "group". Règle correspondant para en mode "group" (également appelé makePara): génère un paragraphe s'il existe un groupe avec le noeud de contexte génère l'ID comme valeur de clé. Règle correspondant à n'importe quel élément du mode "group" (il s'agira de n'importe quel élément "block"): appliquer des modèles à self (mode "reset") et appeler le modèle nommé makePara.

+0

+1 pour une bonne réponse. –

+0

+1 Beau style de groupage. – Flack

+0

merci beaucoup pour cette réponse, cela fonctionne très bien, même si je suis gêné de dire en ce moment je n'ai pas une compréhension intuitive à 100% de la raison pour laquelle cela fonctionne ... lira plus sur les touches et essayer de faire des choses différentes avec cette méthode de base. Merci encore! – badperson

Questions connexes