2013-09-04 15 views
10

ich dieses XML-Dokument haben:XML von CDATA-Transformation XSL

<ns0:getDataResponse xmlns:ns0="http://abc.com/"> 
    <return> 
     <wrapper> 
      <data><![CDATA[<?xml version="1.0" encoding="UTF-8"?> 
          <ConDic> 
          <dictionary>bank</dictionary> 
           <rows> 
            <row> 
             <bic>ABKZKZKX</bic> 
             <bcode>319</bcode> 
             <name1>AA &quot;A BANK&quot;</namekz> 
             <name2>BB &quot;B BANK&quot;</nameru> 
            </row> 
            <row> 
             <bic>ABNAKZKX</bic> 
             <bcode>922</bcode> 
             <name1>CC &quot;C BANK&quot;</namekz> 
             <name2>DD &quot;D BANK&quot;</nameru> 
            </row> 
           </rows> 
          </ConDic>]]></data> 
     </wrapper> 
    </return> 
</ns0:getDataResponse> 

Wie ich es mit XSL analysieren kann je Reihen in CDATA zu bekommen diese Art von Auswahl zu machen:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns0="http://abc.com/"> 
<xsl:output method="html" /> 
<xsl:template match="text()|@*"/> 
<xsl:template match="ns0:rows"> 

<select name="bank" id="bank" class="input" style="width: 370px;"> 
    <xsl:for-each select="row"> 
     <xsl:sort select="name1"/> 
     <option value="{bic}"><xsl:value-of select="name1" /></option> 
    </xsl:for-each> 
</select> 
+7

Welche XSLT-Prozessor verwenden Sie? Sie benötigen einen XSLT 3.0-Prozessor mit der 3.0-Funktion http://www.w3.org/TR/2013/CR-xpath-functions-30-20130108/#func-parse-xml oder Sie benötigen einen XSLT 1.0- oder 2.0-Prozessor, der unterstützt eine Erweiterungsfunktion wie http://www.saxonica.com/documentation/index.html#!functions/saxon/parse. –

+1

Dieses ausgeblendete Markup ist kein gültiges XML. Es gibt keine Entität '"' definiert und es gibt keine DTD-Referenzen. Selbst wenn Sie eine First-Pass-Transformation zum Extrahieren der CDATA mit disable-output-escaping verwenden, bleibt ein ungültiges Markup, das nicht als XML analysiert wird. Außerdem enthält es die XML-Deklaration, die das Hinzufügen einer DTD-Referenz in der DOE-Transformation erschwert. Gibt es eine Möglichkeit, den Hersteller des Webservice dazu zu bringen, seine Ausgabe zu ändern? –

+1

http://www.w3.org/TR/xml/#sec-predefined-ent definiert 'quot', so dass es keine DTD geben muss, um es zu definieren. –

Antwort

0

Wenn Sie haben die exslt Erweiterungen verfügbar, sollten Sie exslt:node-set verwenden können, um eine Variable des Inhalts zu erstellen. Versuchen Sie etwas wie (ungetestet):

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common" 
    extension-element-prefixes="exsl" 
    exclude-result-prefixes="exsl" 
    version="1.0"> 

<xsl:template match="/"> 
    <xsl:variable name="inner" select="exsl:node-set(//data/text())" /> 
    <select name="bank" id="bank" class="input" style="width: 370px;"> 
     <xsl:for-each select="$inner//row"> 
      ... 
     </xsl:for-each> 
    </select> 
</xsl:template> 

</xsl:stylesheet> 
+0

Die Funktion 'node-set()' benötigt ein * Ergebnisbaumfragment * und konvertiert es in eine Knotenmenge. Es wird keine Zeichenfolge benötigt und in eine Knotenmenge zerlegt. Im besten Fall ist der Wert von "$ inner" nur eine Zeichenkette, und Sie können nicht "$ inner // row" auswählen. – LarsH

1

Wie in einem Kommentar vorgeschlagen, poste ich eine Lösung. Das Beispiel für die Verwendung von XSLT 3.0 mit Saxon 9.5 (benötigt PE oder EE-Version):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:ns0="http://abc.com/" 
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" exclude-result-prefixes="xs math ns0" 
    version="3.0"> 


    <xsl:output method="html" indent="yes"/> 

    <xsl:template match="text()|@*"/> 

    <xsl:template match="ns0:getDataResponse"> 

     <select name="bank" id="bank" class="input" style="width: 370px;"> 
      <xsl:for-each select="parse-xml(return/wrapper/data)//row"> 
       <xsl:sort select="name1"/> 
       <option value="{bic}"> 
        <xsl:value-of select="name1"/> 
       </option> 
      </xsl:for-each> 
     </select> 
    </xsl:template> 

</xsl:stylesheet> 

Mit einem Eingang

<ns0:getDataResponse xmlns:ns0="http://abc.com/"> 
    <return> 
     <wrapper> 
      <data><![CDATA[<?xml version="1.0" encoding="UTF-8"?> 
          <ConDic> 
          <dictionary>bank</dictionary> 
           <rows> 
            <row> 
             <bic>ABKZKZKX</bic> 
             <bcode>319</bcode> 
             <name1>AA &quot;A BANK&quot;</name1> 
             <name2>BB &quot;B BANK&quot;</name2> 
            </row> 
            <row> 
             <bic>ABNAKZKX</bic> 
             <bcode>922</bcode> 
             <name1>CC &quot;C BANK&quot;</name1> 
             <name2>DD &quot;D BANK&quot;</name2> 
            </row> 
           </rows> 
          </ConDic>]]></data> 
     </wrapper> 
    </return> 
</ns0:getDataResponse> 

das Ergebnis ist

<select name="bank" id="bank" class="input" style="width: 370px;"> 
    <option value="ABKZKZKX">AA "A BANK"</option> 
    <option value="ABNAKZKX">CC "C BANK"</option></select>