2017-10-04 122 views
0

我正在嘗試創建一個簡單的Jython腳本來執行xslt轉換。使用Jython進行XML XSLT轉換

輸入XML:

<service-config> 
     <service> 
     <request> 
      <rule transform="local:///services/xslt/RequestMapping.xslt">Framework-Policy-Transform</rule> 
     </request> 
     <response> 
      <rule transform="local:///services/xslt/ResponseMapping.xslt">Framework-Policy-Transform</rule> 
     </response> 
     </service> 
    </service-config> 

XSLT -

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:key name="xsltkey" match="/*/*/*/rule[contains(., 'Framework-Policy-Transform')]/@transform" use="."/> 
    <xsl:template match="/" mode="xsltname"> 
     <xsl:variable name="firstoutput"> 
      <xsl:call-template name="firstpass"/> 
     </xsl:variable> 
     <xsl:apply-templates select="mutate">    
      <xsl:with-param name="pr" select="exsl:node-set($firstoutput)/*"/> 
     </xsl:apply-templates> 
    </xsl:template> 
    <xsl:template match="/*" name="firstpass"> 
     <dpXsltTransforms> 
      <xsl:for-each select="/*/*/*/rule[contains(., 'Framework-Policy-Transform')]/@transform[generate-id() 
             = generate-id(key('xsltkey',.)[1])]"> 
       <transform-dpPath> 
        <xsl:value-of select="."/> 
       </transform-dpPath> 
      </xsl:for-each> 
     </dpXsltTransforms> 
    </xsl:template> 
    <xsl:template match="mutate"> 
     <xsl:param name="pr"/> 
     <services-xslt>    
      <xsl:for-each select="pr/transform-dpPath[contains(., 'local:///services/xslt/')]"> 
       <xslt-cognomen> 
        <xsl:value-of select="substring(.,24)"/> 
       </xslt-cognomen> 
      </xsl:for-each> 
     </services-xslt> 
    </xsl:template> 
</xsl:stylesheet> 

預期輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<dpXsltTransforms> 
    <transform-dpPath>local:///services/xslt/RequestMapping.xslt</transform-dpPath> 
    <transform-dpPath>local:///services/xslt/ResponseMapping.xslt</transform-dpPath> 
</dpXsltTransforms> 

Jython腳本 -

from java.io import * 
import javax.xml 
from javax.xml.transform import Transformer, TransformerFactory 
from javax.xml.transform.stream import StreamResult, StreamSource 
from xml.dom import minidom 

def obtainservicexslts(): 


    source_xform_xml = """<service-config> 
     <service> 
     <request> 
      <rule transform="local:///services/xslt/RequestMapping.xslt">Framework-Policy-Transform</rule> 
     </request> 
     <response> 
      <rule transform="local:///services/xslt/ResponseMapping.xslt">Framework-Policy-Transform</rule> 
     </response> 
     </service> 
    </service-config>""" 

    source_xform_xslt = """<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:key name="xsltkey" match="/*/*/*/rule[contains(., 'Framework-Policy-Transform')]/@transform" use="."/> 
    <xsl:template match="/" mode="xsltname"> 
     <xsl:variable name="firstoutput"> 
      <xsl:call-template name="firstpass"/> 
     </xsl:variable> 
     <xsl:apply-templates select="mutate">    
      <xsl:with-param name="pr" select="exsl:node-set($firstoutput)/*"/> 
     </xsl:apply-templates> 
    </xsl:template> 
    <xsl:template match="/*" name="firstpass"> 
     <dpXsltTransforms> 
      <xsl:for-each select="/*/*/*/rule[contains(., 'Framework-Policy-Transform')]/@transform[generate-id() 
             = generate-id(key('xsltkey',.)[1])]"> 
       <transform-dpPath> 
        <xsl:value-of select="."/> 
       </transform-dpPath> 
      </xsl:for-each> 
     </dpXsltTransforms> 
    </xsl:template> 
    <xsl:template match="mutate"> 
     <xsl:param name="pr"/> 
     <services-xslt>    
      <xsl:for-each select="pr/transform-dpPath[contains(., 'local:///services/xslt/')]"> 
       <xslt-cognomen> 
        <xsl:value-of select="substring(.,24)"/> 
       </xslt-cognomen> 
      </xsl:for-each> 
     </services-xslt> 
    </xsl:template> 
</xsl:stylesheet>""" 

    try: 
     transformer = TransformerFactory.newInstance().newTransformer(StreamSource(StringReader(source_xform_xslt))) 
     output_buffer = StringWriter()  
     transformer.transform(StreamSource(StringReader(source_xform_xml)), StreamResult(output_buffer)) 
     print output_buffer.buffer.toString()   
     return output_buffer.buffer.toString() 
    except:     
     raise 


if __name__ == '__main__': 
    obtainservicexslts() 

實際輸出:

<?xml version="1.0" encoding="UTF-8"?><dpXsltTransforms/> 

關於如何對待我的輸入變量在腳本作爲XML而不是字符串,我以爲是不作爲轉型我想原因有什麼想法? ?

感謝您的時間,提前!

+0

這是一個相當大的問題。爲什麼不構建探索你的懷疑所需的最小程序? –

+0

我同意它看起來很大。但實際上這個問題很簡單。如何在jython變量中設置xml,並將其作爲xml而不是字符串讀取。 – VishB

+0

您現在可以忽略xslt。我只是添加了這些參考。 – VishB

回答

0

感謝John Bollinger在另一篇文章中的回答!

這是他的答案 - 之所以這不起作用是因爲Transformer絆倒了generate-id()的用法。 所以按順序),以確定組典範,使用節點集工會和count(

線在XSLT

<xsl:for-each select="/*/*/*/rule[contains(., 'Framework-Policy-Transform')]/@transform[generate-id() 
             = generate-id(key('xsltkey',.)[1])]"> 

需要改變,以

<xsl:for-each select="/*/*/*/rule[contains(., 'Framework-Policy-Transform')]/@transform[count(. | key('xsltkey',.)[1]) = 1]"> 

和Jython腳本作品!