0

我是 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>

谁能帮我这个?提前致谢

4

2 回答 2

0

回答这个问题有点晚了,但它适用于任何可能有同样问题的人,

对于缩进问题,我必须使用自定义 xsl 模板来确保输出 xml 以我想要的方式缩进。

该模板包含许多脏代码,这些代码强制 xml 标记具有模拟缩进的特殊间距

希望这有帮助:)

于 2014-03-27T16:52:23.787 回答
0

XSLT 变量只能包含字符串、布尔值、数字或节点集——Color:new(...)调用返回一个 Java 对象,该对象不能分配给 XSLT 变量,因此出现异常。

可能的解决方案:

stringToRed1)使用定义的方法等创建您自己的扩展类,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(.) &gt;=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>

这种方法的问题在于 XSLT 使用浮点运算,因此在某些情况下舍入错误可能会导致组件的错误值。

于 2012-12-27T18:10:12.693 回答