【问题标题】:XSLT cannot transform if there is a German character如果存在德语字符,XSLT 无法转换
【发布时间】:2011-06-21 20:23:52
【问题描述】:

我正在使用 1.0 版 XSLT,但德语字符有问题。如果 XML 元素数据中有任何德语字符,则 XSLT 无法转换任何内容,并且输出完全为空。

一个简单的例子:

<root>
  <table name="users">
   <row>
     <field attr1="name">GÜNTER</field>
   </row>
  </table>
</root>

输出应该是:

<users>
  <name>GUENTER</name>
</users>

我在 XSL 中使用 utf-8 编码,当我使用 Eclipse 时可以对其进行转换。在我的应用程序中,这些 XSL 文件存储在 Oracle 数据库中,并在应用程序启动时进行缓存。但我的 Java 应用程序无法对此进行转换并抛出此错误:

2 字节 UTF-8 序列的字节 2 无效

这是主要的 XSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:include href="functions.xsl" />
    <xsl:output encoding="utf-8" method="xml" indent="yes" />
    <xsl:template match="/">
        <users>
            <name>
                <xsl:call-template name="replaceCH">
                    <xsl:with-param name="value" select="//root/table[@name='users']/row/field[@attr1='name']"/>
                </xsl:call-template>
            </name>
        </users>    
    </xsl:template>
</xsl:stylesheet>

这里是functions.xsl:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="replace">
    <xsl:param name="text"/>
    <xsl:param name="search"/>
    <xsl:param name="replace"/>
    <xsl:choose>
        <xsl:when test="contains($text, $search)">
            <xsl:variable name="replace-next">
                <xsl:call-template name="replace">
                    <xsl:with-param name="text" select="substring-after($text, $search)"/>
                    <xsl:with-param name="search" select="$search"/>
                    <xsl:with-param name="replace" select="$replace"/>
                </xsl:call-template>
            </xsl:variable>
            <xsl:value-of select="concat(substring-before($text, $search),$replace,$replace-next)"/>
        </xsl:when>
        <xsl:otherwise><xsl:value-of select="$text"/></xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="replaceCH">
    <xsl:param name="value"/>
        <xsl:variable name="temp">
        <xsl:call-template name="replace">
            <xsl:with-param name="text" select="$value"/>
            <xsl:with-param name="search" select="'_'"/>
            <xsl:with-param name="replace" select="''"/>
        </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="temp1">
            <xsl:call-template name="replace">
                <xsl:with-param name="text" select="$temp"/>
                <xsl:with-param name="search" select="'Ö'"/>
                <xsl:with-param name="replace" select="'OE'"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="temp2">
            <xsl:call-template name="replace">
                <xsl:with-param name="text" select="$temp1"/>
                <xsl:with-param name="search" select="'Ü'"/>
                <xsl:with-param name="replace" select="'UE'"/>
            </xsl:call-template>
        </xsl:variable> 
        <xsl:value-of select="$temp2"/>     
    </xsl:template>
</xsl:stylesheet>

当我将 XSL 存储到数据库时,Ö 和 Ü 看起来像 Ã?

<xsl:with-param name="search" select="'Ã?'"/>

我使用 Hibernate 并配置如下编码:

hibernate.connection.characterEncoding=utf-8

我该如何解决这个问题?

【问题讨论】:

  • 听起来问题在于您从 Oracle 获取 XSL 的方式 - 而您还没有证明...
  • 你说得对。抱歉,我认为问题在于将 xsl 内容存储在 Oracle 中。当我将包含德语字符的 xsl 存储在 html 编码“Ü”中时和喜欢 Ö 。当我从 db 检查“Ö”时,它看起来像“Ã?”。和?如果我是对的,会导致此错误。你有什么建议?
  • 我认为 Jon 会建议像他所说的那样展示存储和获取数据的代码 ;-) Oracle 无疑能够存储 unicode 数据,但毕竟有几种不同的方式来存储 xml 数据
  • 我知道,但是 thx :) 正如我之前所说,我使用 hibernate 并且仅使用诸如 save() 之类的休眠函数,并且不使用任何特殊的编码设置来代替 hibernate.connection.characterEncoding=utf-8 .我会寻找方法。谢谢
  • 通常带重音符号的 A 表示某处 utf-8 被解释为 ascii/cp1252。你有很多步骤要完成,但是某个地方的某个人(oracle、hibernate、xml 解析器、xsl 引擎、其他??)正试图将 utf-8 解释为 ascii/cp1252

标签: java xml xslt xslt-1.0


【解决方案1】:

XML 解析器将您的 XML 源视为 UTF-8 格式,但它不是 UTF-8 格式,而是其他一些编码格式,例如 CP1252 或 ISO8859-1。

您提供给我们的信息无法确定为什么会这样。

【讨论】:

  • 谢谢回答。我怀疑是 Oracle 编码,因为这种情况只发生在我将 xsl 文件存储在 db 中时。也许,这就是为什么有关案件所需的信息不充分的原因。对于那个很抱歉。我解决了我的问题。我会尽快写出解决方案。但如果我简单解释一下,我将两个 xsl 的编码都定义为 UTF-8。
【解决方案2】:

我已经开始使用 html 代码来表示德语字符并且它可以工作。

functions.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="utf-8" method="xml" indent="yes" />
<xsl:template name="replace">
    <xsl:param name="text"/>
    <xsl:param name="search"/>
    <xsl:param name="replace"/>
    <xsl:choose>
        <xsl:when test="contains($text, $search)">
            <xsl:variable name="replace-next">
                <xsl:call-template name="replace">
                    <xsl:with-param name="text" select="substring-after($text, $search)"/>
                    <xsl:with-param name="search" select="$search"/>
                    <xsl:with-param name="replace" select="$replace"/>
                </xsl:call-template>
            </xsl:variable>
            <xsl:value-of select="concat(substring-before($text, $search),$replace,$replace-next)"/>
        </xsl:when>
        <xsl:otherwise><xsl:value-of select="$text"/></xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="replaceCH">
    <xsl:param name="value"/>
        <xsl:variable name="temp">
        <xsl:call-template name="replace">
            <xsl:with-param name="text" select="$value"/>
            <xsl:with-param name="search" select="'_'"/>
            <xsl:with-param name="replace" select="''"/>
        </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="temp1">
            <xsl:call-template name="replace">
                <xsl:with-param name="text" select="$temp"/>
        <xsl:with-param name="search" select="'&#214;'"/>
                <xsl:with-param name="replace" select="'OE'"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="temp2">
            <xsl:call-template name="replace">
                <xsl:with-param name="text" select="$temp1"/>
        <xsl:with-param name="search" select="'&#220;'"/>
                <xsl:with-param name="replace" select="'UE'"/>
            </xsl:call-template>
        </xsl:variable> 
        <xsl:value-of select="$temp2"/>     
    </xsl:template>
</xsl:stylesheet>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多