2016-05-22 12 views
0

Ich habe ein Problem beim Abgleich verschiedener Bezeichner in einer XSL-Transformation von XML zu HTML. Ich habe eine lange Liste von Verbindungselementen, wie folgt aus:Wie Identifikatoren übereinstimmen?

<link target="#E_1 #FCB_1 #FWH_2 #FWH_3"> 

Jeder Text mit # in das Zielattribut entspricht einem xml beginnen: innerhalb eines Absatzes Element wie folgt id-Attribut:

<p xml:id="E_1">text text text</p> 
<p xml:id="FCB_1">text text text</p> 
<p xml:id="FWH_2">text text text</p> 
<p xml:id="FWH_3">text text text</p> 

Was ich tun müssen, ist ein div-Element für jedes Zielattribut zu schaffen, zu erhalten, was bedeutet folgendes: Variable, xsl:

<div class="impair"> 
<div> 
<p>Content of the paragraph with xml:id equal to "E_1"</p> 
</div> 
<div> 
<p>Content of the paragraph with xml:id equal to "FCB_1"</p> 
</div> 
<div> 
<p>Content of the paragraph with xml:id equal to "FWH_2"</p> 
</div> 
<div> 
<p>Content of the paragraph with xml:id equal to "FWH_3"</p> 
</div> 
</div> 

ich mehrere Dinge mit xsl versucht haben, param, xsl: key oder Funktionen li ke beginnt - mit oder sogar Teilstring, aber nichts funktioniert für jetzt. Also bitte ich um Hilfe. Ich versuche immer noch, meine XSL-Fähigkeiten zu verbessern ... Vielen Dank im Voraus für Ihre Hilfe. Flo

+0

Verwenden Sie einen XSLT 2.0 Prozessor wie Saxon 9? –

Antwort

1

einen XSLT 2.0 Prozessor Vorausgesetzt, dass Sie die id Funktion mit den Zeichen übersetzten Werten aus dem target Attribute verwenden:

<xsl:template match="link[@target]"> 
    <div class="impair"> 
     <xsl:apply-templates select="id(for $idref in tokenize(@target, '\s+') return substring($idref, 2))" mode="wrap"/> 
    </div> 
</xsl:template> 

<xsl:template match="p" mode="wrap"> 
    <div> 
     <xsl:copy> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </div> 
</xsl:template> 
0

Wenn Sie nach einer XSLT 1.0-Lösung suchen, hier ist ein mögliches Verfahren, die wandelt das target-Attribut in die Zeichenfolge #E_1#FCB_1#FWH_2#FWH_3# um und verwendet verschiedene Zeichenfolgenfunktionen, um die Elemente auszuwählen, deren id in dieser Zeichenfolge auftritt.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="//link" /> 
    </xsl:template> 

    <xsl:template match="link"> 
    <xsl:variable name="target" select="concat(translate(@target, ' ', ''), '#')" /> 
    <xsl:value-of select="$target" /> 
    <div class="impair"> 
     <xsl:apply-templates select="//p[contains($target, concat('#', @xml:id, '#'))]"> 
     <xsl:sort select="string-length(substring-before($target, concat('#', @xml:id, '#')))" /> 
     </xsl:apply-templates> 
    </div> 
    </xsl:template> 

    <xsl:template match="p"> 
    <div> 
     <p><xsl:value-of select="." /></p> 
    </div> 
    </xsl:template> 
</xsl:stylesheet> 

Dies würde nicht funktionieren, wenn Sie zwar ids im target Attribut wiederholt hatte, wie #E_1 #FCB_1 #FWH_3 #FWH_3. In diesem Fall wird ein rekursiv aufgerufen Named-Vorlage könnte die target Attribut aufzuspalten arbeiten:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:key name="p" match="p" use="concat('#', @xml:id)" /> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="//link" /> 
    </xsl:template> 

    <xsl:template match="link"> 
    <div class="impair"> 
     <xsl:call-template name="split"> 
      <xsl:with-param name="string" select="@target" /> 
     </xsl:call-template> 
    </div> 
    </xsl:template> 

    <xsl:template name="split"> 
    <xsl:param name="string" /> 
    <xsl:if test="$string != ''"> 
     <xsl:apply-templates select="key('p', substring-before(concat($string, ' '), ' '))" /> 
     <xsl:if test="contains($string, ' ')"> 
     <xsl:call-template name="split"> 
      <xsl:with-param name="string" select="substring-after($string, ' ')" /> 
     </xsl:call-template> 
     </xsl:if> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="p"> 
    <div> 
     <p><xsl:value-of select="." /></p> 
    </div> 
    </xsl:template> 
</xsl:stylesheet> 
Verwandte Themen