使用Jython进行XML XSLT转换
问题描述:
我正在尝试创建一个简单的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而不是字符串,我以为是不作为转型我想原因有什么想法? ?
感谢您的时间,提前!
答
感谢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脚本作品!
这是一个相当大的问题。为什么不构建探索你的怀疑所需的最小程序? –
我同意它看起来很大。但实际上这个问题很简单。如何在jython变量中设置xml,并将其作为xml而不是字符串读取。 – VishB
您现在可以忽略xslt。我只是添加了这些参考。 – VishB