2016-05-16 10 views
0

Ich versuche, ein Problem im Zusammenhang mit Xpath zu debuggen. Ich habe eine Variable $ MetaData in meinem XSLT erstellt, die ein XML-Dokument zuweist, aber aus irgendeinem Grund konnte foreach loop sein Kind nicht lokalisieren und ich konnte nicht in die foreach-Schleife gelangen.XSLT kann XPATH für for-each nicht finden

XSLT:

<!-- language: lang-xslt --> 
<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet 
    version="1.0" 
    xmlns="http://www.w3.org/TR/xhtml1/strict" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"> 

    <xsl:variable name="_MetaData"> 
    <MetaData> 
     <EmployeeId>1233</EmployeeId> 
     <EmployeeName>abcd</EmployeeName> 
    </MetaData> 
    </xsl:variable> 
    <xsl:variable name="MetaData" select="msxsl:node-set($_MetaData)"></xsl:variable> 

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

    <xsl:template match="*[local-name()='MetaDataTag']"> 
    <xsl:copy> 

     <MetaData VocabularyOwner="acme.com" Vocabulary="MetaData"> 
     <xsl:for-each select="$MetaData//MetaData/*"> 
      <xsl:element name="Occurrence"> 
      <xsl:attribute name="Id"> 
       <xsl:value-of select="local-name(.)"/> 
      </xsl:attribute> 
      <xsl:attribute name="Value"> 
       <xsl:value-of select="string(.)"/> 
      </xsl:attribute> 
      </xsl:element> 
     </xsl:for-each> 
     </MetaData> 

    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

XML:

<?xml version="1.0" encoding="utf-8" ?> 
<Envelope> 
    <MetaDataTag /> 
</Envelope> 

Wenn ich Xmlns Xmlns entfernen = "http://www.w3.org/TR/xhtml1/strict" Namespace, alles scheint funktioniert gut und ich bin in der Lage, in die Schleife zu kommen. Ich bin mir nicht sicher, wie ich dieses Problem lösen kann, ohne den Namensraum xmlns = "http://www.w3.org/TR/xhtml1/strict" zu entfernen.

Antwort

1

Wenn Sie den Standard-Namespace in XSLT definieren, befinden sich die Knoten in Ihrer Variablen in diesem Namespace. Xpath hat keinen Standard-Namespace, so dass $MetaData//MetaData/* nicht mit dem Elementknoten {http://www.w3.org/TR/xhtml1/strict}MetaData übereinstimmt.

Eine Lösung besteht darin, die Namespaces mit local-name() zu ignorieren.

`$MetaData//*[local-name() = 'MetaData']/*` 

Oder Sie können einen (zusätzlichen) Präfix für XPath-Ausdrücke ...

<xsl:stylesheet 
    version="1.0" 
    xmlns="http://www.w3.org/TR/xhtml1/strict" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xhtml="http://www.w3.org/TR/xhtml1/strict"> 

    ... 
</xsl:stylesheet> 

... und verwenden Sie es in dem Ausdruck definieren.

`$MetaData//xhtml:MetaData/*` 

Aber die Tags sind im XHTML-Namensraum nicht gültig, so wäre es eine bessere Idee, um die Datenelemente in dem leeren Namensraum sein:

<xsl:variable name="_MetaData"> 
    <MetaData xmlns=""> 
    <EmployeeId>1233</EmployeeId> 
    <EmployeeName>abcd</EmployeeName> 
    </MetaData> 
</xsl:variable> 
<xsl:variable name="MetaData" select="msxsl:node-set($_MetaData)"/> 

Oder Sie einen bestimmten Namensraum für sie zu definieren .. . im Ausdruck

<xsl:stylesheet 
    version="1.0" 
    xmlns="http://www.w3.org/TR/xhtml1/strict" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:data="urn:data"> 

    <xsl:variable name="_MetaData"> 
    <data:MetaData> 
     <data:EmployeeId>1233</data:EmployeeId> 
     <data:EmployeeName>abcd</data:EmployeeName> 
    </data:MetaData> 
    </xsl:variable> 
    <xsl:variable name="MetaData" select="msxsl:node-set($_MetaData)"/> 
    ... 
</xsl:stylesheet> 

zu verwenden:

$MetaData//data:MetaData/*