2017-03-03 3 views
1

XSLT lernen!Zugreifen auf Attribute von dynamisch erstellten Geschwisterelementen

Ich habe ein XML-Source-Tree-Fragment, das wie folgt aussieht:

Mit Saxon und XSLT 2.0 zu verwandeln ...

<?xml version = "1.0" encoding = "UTF-8"?> 
    <Chapter revision="B" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
     <Content Ref="X123"> 
      <Ref name="INT1"/> 
      <Ref name="INT2"/> 
      <Ref name="INT3"/> 
      <Ref name="INT4"/> 
      <Ref name="INT5"/> 
     </Content> 
     <Data> 
      <Reference name="INT1" Function="CONDUCTOR"></Reference> 
      <Reference name="INT2" Function="SIGNAL"></Reference> 
      <Reference name="INT3" Function="MIXED"></Reference> 
      <Reference name="INT4" Function="PLANE"></Reference> 
      <Reference name="INT5" Function="CORE"></Reference> 
     </Data> 
    </Chapter> 

Ich will es, dies produzieren:

<Chapter> 
    <Content> 
     <Ref id="INT1" Function="CONDUCTOR">INT1</Ref> 
     <Ref id="INT2" Function="SIGNAL">INT2</Ref> 
     <Ref id="INT3" Function="MIXED">INT3</Ref> 
     <Ref id="INT4" Function="PLANE">INT4</Ref> 
     <Ref id="INT5" Function="CORE">INT5</Ref> 
    </Content> 
</Chapter> 

Hier ist meine Vorlage Fragment:

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

<xsl:template match="/Chapter"> 
    <xsl:element name="{name()}"> 
     <xsl:apply-templates select="Content"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="Content"> 
    <xsl:element name="{name()}"> 
     <xsl:apply-templates select="Ref"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="Ref"> 
    <xsl:element name="{name()}"> 

     <xsl:attribute name="id"> 
      <xsl:value-of select="@name"/> 
     </xsl:attribute> 

     <xsl:attribute name="Function"> 
      <xsl:value-of select="/Chapter/Data/Reference[@name=/Chapter/Data/Reference/@name]/@Function"/> 
     </xsl:attribute> 

     <xsl:value-of select="@name"/> 

    </xsl:element> 
</xsl:template> 

Aber die Vorlage oben ergibt dies: Es ist offensichtlich die Werte von jedem Knoten

<Chapter> 
     <Content> 
      <Ref id="INT1" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT1</Ref> 
      <Ref id="INT2" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT2</Ref> 
      <Ref id="INT3" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT3</Ref> 
      <Ref id="INT4" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT4</Ref> 
      <Ref id="INT5" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT5</Ref> 
     </Content> 
    </Chapter> 

Was brauche ich Aufnehmen als Prädikat Wert liefern durch die Attributwerte zu treten?

Vielen Dank

Antwort

0

ändern /Chapter/Data/Reference[@name=/Chapter/Data/Reference/@name]/@Function-/Chapter/Data/Reference[@name=current()/@name]/@Function, dann über Tasten lernen und definiert <xsl:key name="ref" match="Data/Reference" use="@name"/> und verwendet key('ref', @name)/@Function statt Leistung und Lesbarkeit zu verbessern.

Im Allgemeinen möchten Sie vielleicht über literale Ergebniselemente und Attributwert-Templates lernen, so dass

<xsl:template match="Ref"> 
    <xsl:element name="{name()}"> 

     <xsl:attribute name="id"> 
      <xsl:value-of select="@name"/> 
     </xsl:attribute> 

     <xsl:attribute name="Function"> 
      <xsl:value-of select="/Chapter/Data/Reference[@name=/Chapter/Data/Reference/@name]/@Function"/> 
     </xsl:attribute> 

     <xsl:value-of select="@name"/> 

    </xsl:element> 
</xsl:template> 

wird
<xsl:template match="Ref"> 
    <Ref id="{@name}" Function="{key('ref', @name)/@Function}"> 
     <xsl:value-of select="@name"/> 
    </Ref> 
</xsl:template> 

und der vollständige Code ist

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 

    <xsl:key name="ref" match="Data/Reference" use="@name"/> 

    <xsl:template match="/Chapter"> 
     <xsl:copy copy-namespaces="no"> 
      <xsl:apply-templates select="Content"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Content"> 
     <xsl:copy copy-namespaces="no"> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Ref"> 
     <Ref id="{@name}" Function="{key('ref', @name)/@Function}"> 
      <xsl:value-of select="@name"/> 
     </Ref> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Martin, Viele Danke für deine Lösung. Funktioniert wunderbar. Und ich danke Ihnen für Ihre weiteren Vorschläge und dafür, dass Sie mich auf weitere Studiengebiete aufmerksam gemacht haben. Sehr dankbar für Ihre Zeit und Mühe! Ralph –

+0

Ich habe Ihren Vorschlag verwendet:/Kapitel/Daten/Referenz [@ name = aktuell()/@ name]/@ Funktion –

+0

Martin, ich habe Ihren Vorschlag von /Kapitel/Daten/Referenz [@ name = current ()/@ name]/@ Funktion und es funktioniert gut. Wie würde ich die Funktion mit dem vorherigen Namen verknüpft bekommen? Ich habe versucht, [@ Name = Vorgänger-Geschwister :: * [1]/@ Name] im Prädikat, aber es gibt nichts zurück. Hat current() denselben Kontext wie vorhergehende Geschwister? Ralph B –

Verwandte Themen