我是XSL的新手,我有一个带有代表int rgb颜色的标签的xml文件, 我想使用XSL将它们转换为Color对象标记:
我的xml包含这些标记
<?xml version="1.0" encoding="UTF-8"?>
.
.
.
<ForeGroundColour>-16776961</ForeGroundColour>
.
.
.
</xml>
所需的xml是:
<ForeGroundColour>
<red>102</red>
<blue>102</blue>
<green>255</green>
<alpha>255</alpha>
</ForeGroundColour>
我的XSL文件是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:Color="java.awt.Color"
xmlns:Integer="java.lang.Integer" exclude-result-prefixes="Color Integer ">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<!-- identity template !-->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="//*[contains(name(),'ForegroundColour')]">
<xsl:copy>
<xsl:variable name="rgb" select="." />
<xsl:variable name="color" select="Color:new(Integer:parseInt($rgb))" />
<xsl:element name="red">
<xsl:value-of select="Color:getRed($color)" />
</xsl:element>
<xsl:element name="blue">
<xsl:value-of select="Color:getBlue($color)" />
</xsl:element>
<xsl:element name="green">
<xsl:value-of select="Color:getGreen($color)" />
</xsl:element>
<xsl:element name="alpha">
<xsl:value-of select="Color:getAlpha($color)" />
</xsl:element>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有两个问题:
1-当我运行此代码时,我得到以下异常:
Exception in thread "main" java.lang.VerifyError: (class: transformer, method: template$dot$1 signature: (Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;I)V) Expecting to find double on stack
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
at java.lang.Class.getConstructor0(Class.java:2699)
at java.lang.Class.newInstance0(Class.java:326)
at java.lang.Class.newInstance(Class.java:308)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getTransletInstance(TemplatesImpl.java:364)
at com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.newTransformer(TemplatesImpl.java:394)
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:649)
at com.nyfix.ostp.server.workspacemigrator.XMLTransformer.transform(XMLTransformer.java:44)
at com.nyfix.ostp.server.workspacemigrator.XSLMigrator.migrate(XSLMigrator.java:45)
at com.nyfix.ostp.server.workspacemigrator.WorkspaceMigratorFactory.<init>(WorkspaceMigratorFactory.java:19)
at com.nyfix.ostp.server.workspacemigrator.WorkspaceMigratorFactory.main(WorkspaceMigratorFactory.java:45)
2-当我使用模板来测试插入的节点时,
<xsl:template match="//*[contains(name(),'ForegroundColour')]">
<xsl:copy>
<xsl:variable name="rgb" select="." />
<xsl:element name="red">
<xsl:value-of select="$rgb" />
</xsl:element>
<xsl:element name="blue">
<xsl:value-of select="$rgb" />
</xsl:element>
<xsl:element name="green">
<xsl:value-of select="$rgb" />
</xsl:element>
<xsl:element name="alpha">
<xsl:value-of select="$rgb" />
</xsl:element>
</xsl:copy>
</xsl:template>
在没有缩进的情况下转换xml:
<ForegroundColour>
<red>-16776961</red>
<blue>-16776961</blue>
<green>-16776961</green>
<alpha>-16776961</alpha>
</ForegroundColour>
任何人都可以帮我这个吗?提前谢谢
答案 0 :(得分:0)
XSLT变量只能包含字符串,布尔值,数字或节点集 - Color:new(...)
调用返回一个Java对象,该对象无法分配给XSLT变量,因此是异常。
可能的解决方案:
1)创建自己的扩展类,定义方法stringToRed
,stringToBlue
等,以便它们接受一个字符串,将其内部转换为Color
对象,然后提取所需的组件(红色,蓝色等)作为数字或字符串。然后可以直接使用这些函数:
<xsl:element name="red">
<xsl:value-of select="MyColorFunctions:stringToRed(.)" />
</xsl:element>
2)'逆向工程'将表示为整数的颜色转换为其组件的算法,并在XSLT中直接实现,而不使用扩展函数。通常,红色分量将是8个最低有效位,蓝色是接下来的8位,依此类推(反之亦然),并且您必须处理负值(从2补码转换为绝对值) - 所以类似这样的东西:
<xsl:variable name="color">
<xsl:choose>
<xsl:when test="number(.) >=0">
<xsl:value-of select="number(.)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="4278190080+number(.)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<red>
<xsl:value-of select="floor($color mod 256)" />
</red>
<green>
<xsl:value-of select="floor(($color div 256) mod 256)" />
</green>
<blue>
<xsl:value-of select="floor(($color div 65536) mod 256)" />
</blue>
<alpha>
<xsl:value-of select="floor(($color div 16777216) mod 256)" />
</alpha>
这个apprach的问题是XSLT使用浮点算术,因此在某些情况下,舍入错误可能会导致组件的错误值。
答案 1 :(得分:0)
回答这个问题有点晚了,但是对于那些可以遇到同样问题的人来说,
对于indenation问题,我不得不使用自定义xsl模板来确保输出xml以我想要的方式进行。
该模板包含许多脏代码,这些代码强制xml标记具有模拟缩进的特殊间距
希望这有帮助:)