2016-09-05 4 views
0

Ich mag Mit Doppel-Lookup-Funktion, implementieren mußeinen verschachtelten Schlüssel in foreach

ich in <Product> mit dem Wert der äußeren XML-Wert von <Node2> Elemente einzustellen.
Die Beziehung zu dieser xml, ist über <lookup> Element über Wert von <ID>

<?xml version="1.0" encoding="utf-8"?> 
<Products> 
    <lookup> 
     <Ref> 
      <ID>1</ID> 
      <outer_id>110</outer_id> 
     </Ref> 
     <Ref> 
      <ID>2</ID> 
      <outer_id>220</outer_id> 
     </Ref> 
    </lookup> 
    <Product> 
     <item> 
     <ID>1</ID> 
     <Node2>A</Node2> 
     </item> 
     <item> 
     <ID>2</ID> 
     <Node2>B</Node2> 
     </item>    
    </Product> 
</Products> 


<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:param name="f1" select="'xml2.xml'"/> 
    <xsl:variable name="doc1" select="document($f1)"/> 

    <xsl:key name="k1" match="Products/Product" use="@prodId"/> 

    <xsl:key name="look" match="Products/lookup/Ref/outer_id" use="../ID"/> 

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


    <xsl:template match="Products/Product/item/Node2"> 

     <xsl:variable name="cur" select="current()"/> 
     <xsl:copy> 
      <xsl:choose> 
       <xsl:when test="key('look', normalize-space(normalize-space($cur/../ID)))">     
        <xsl:for-each select="$doc1"> 
         <xsl:value-of select="key('k1', key('look', normalize-space(normalize-space($cur/../ID))))/@myvalue"/> 
        </xsl:for-each> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:copy> 

    </xsl:template> 
</xsl:stylesheet> 

Es ist wie eine nicht sehr komplexe Aufgabe aussieht, aber es für mich nicht funktioniert, ich aufgrund der Tatsache, denke, dass mein ‚Kontext 'ist innerhalb foreach geändert und es ist nicht mehr möglich,' Look 'Taste zu verwenden.

Bitte schlagen Sie eine Lösung vor.

+0

Ihr XSLT verweist auf einen zweiten XML-Dokument; 'xml2.xml'. Können Sie ein Beispiel in Ihrer Frage und der erwarteten Ausgabe zeigen? Vielen Dank! –

+0

Was erreicht 'normalize-space (normalize-space (..))', dass 'normalize-space (...)' nicht wäre? –

+0

ja :), nachdem ich die Schlüssel separat getestet habe, kopiere ich den Inhalt in den anderen Schlüssel / – yuris

Antwort

0

Das Problem in der Tat eines der Kontext, wie in der <xsl:for-each select="$doc1"> Aussage, jede Verwendung von key('look', ...) wird im Kontext von $doc1 und nicht das ursprüngliche XML-Dokument sein.

In diesem Fall besteht die Lösung einfach darin, den Schlüssel auszuwerten und die Ergebnisse in eine Variable vor dem xsl:for-each zu schreiben und die Variable im Inneren zu verwenden.

<xsl:template match="Products/Product/item/Node2"> 
    <xsl:variable name="cur" select="current()"/> 
    <xsl:copy> 
     <xsl:variable name="look" select="key('look', normalize-space(normalize-space($cur/../ID)))" /> 
     <xsl:choose> 
      <xsl:when test="$look">     
       <xsl:for-each select="$doc1"> 
        <xsl:value-of select="key('k1', $look)/@myvalue"/> 
       </xsl:for-each> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:copy> 
</xsl:template> 
Verwandte Themen