gpt4 book ai didi

java - JAXB 将非 ASCII 字符转换为 ASCII 字符

转载 作者:搜寻专家 更新时间:2023-10-31 19:38:57 25 4
gpt4 key购买 nike

我有一些元素名称包含非 ASCII 字符的 xsd 模式。当我使用 生成 java 类时生成 JAXB 类 命令使用 Eclipse Kepler,生成的类和它们的变量包含非 ASCII 字符。我想将此非 ASCII 字符转换为 ASCII 字符。

我已经在 J​​AVA_TOOL_OPTIONS 设置了语言环境

-Duser.country=GB -Duser.language=en

例如
İ -> I
Ç -> C
Ş -> S
Ö -> O
Ğ -> G
Ü -> U
ı -> i
ö -> o
ü -> u
ç -> c
ğ -> g
ş -> s

最佳答案

编辑:由于需求是通用解决方案和 不使用外部绑定(bind)文件 , 我提供了以下 2 个选项:

选项 1 - 通用解决方案 - 创建自定义 XJC 插件来规范化

通用解决方案是有效的:

  • 扩展 com.sun.tools.xjc.Plugin JAXB 的抽象类和覆盖方法用于命名工件 - 基本创建插件
  • 将此实现打包在 jar 中在 services 中专门调出实现的名称后META-INF的目录jar 内的文件夹
  • 部署这个新创建的 jar 和 jaxb库并通过 ANT 运行它(build.xml 下面提供,请继续阅读)

  • 为了您的目的,我创建了插件,您可以从 here 下载 jar 文件。 , 从 here 下载 ant 脚本 ( build.xml ) .将 jar 放入 eclipse 中的构建路径并编辑 ant 文件以提供 JAXB 库的位置、生成的类的目标包、项目名称和模式位置并运行它。 就是这样!

    说明:

    我创建了一个自定义 XJC带有额外命令行选项的插件 -normalize将您创建的 Java 类、方法、变量、属性和接口(interface)中的重音字符替换为它们的 ASCII等价物。
    XJC具有创建自定义插件的能力,可以控制生成的类、变量等的名称、注释和其他属性。 This blog post尽管 old 可以让您开始使用此类插件实现的基础知识。

    长话短说,我创建了一个扩展抽象的类 com.sun.tools.xjc.Plugin类,覆盖其方法重要的是 onActivated .

    在这个方法中,我设置了 com.sun.tools.xjc.Option#setNameConverter到一个自定义类,它负责覆盖获取类名称、方法等所需的方法。我已将源提交给我的 git repo here同样,下面是它的详细用法:
    import java.text.Normalizer;

    import org.xml.sax.ErrorHandler;
    import org.xml.sax.SAXException;

    import com.sun.tools.xjc.BadCommandLineException;
    import com.sun.tools.xjc.Options;
    import com.sun.tools.xjc.Plugin;
    import com.sun.tools.xjc.outline.Outline;
    import com.sun.xml.bind.api.impl.NameConverter;

    /**
    * {@link Plugin} that normalized the names of JAXB generated artifacts
    *
    * @author popofibo
    */
    public class NormalizeElements extends Plugin {

    /**
    * Set the command line option
    */
    @Override
    public String getOptionName() {
    return "normalize";
    }

    /**
    * Usage content of the option
    */
    @Override
    public String getUsage() {
    return " -normalize : normalize the classes and method names generated by removing the accented characters";
    }

    /**
    * Set the name converted option to a delegated custom implementation of
    * NameConverter.Standard
    */
    @Override
    public void onActivated(Options opts) throws BadCommandLineException {
    opts.setNameConverter(new NonAsciiConverter(), this);
    }

    /**
    * Always return true
    */
    @Override
    public boolean run(Outline model, Options opt, ErrorHandler errorHandler)
    throws SAXException {
    return true;
    }

    }

    /**
    *
    * @author popofibo
    *
    */
    class NonAsciiConverter extends NameConverter.Standard {

    /**
    * Override the generated class name
    */
    @Override
    public String toClassName(String s) {
    String origStr = super.toClassName(s);
    return normalize(origStr);
    }

    /**
    * Override the generated property name
    */
    @Override
    public String toPropertyName(String s) {
    String origStr = super.toPropertyName(s);
    return normalize(origStr);
    }

    /**
    * Override the generated variable name
    */
    @Override
    public String toVariableName(String s) {
    String origStr = super.toVariableName(s);
    return normalize(origStr);
    }

    /**
    * Override the generated interface name
    */
    @Override
    public String toInterfaceName(String s) {
    String origStr = super.toInterfaceName(s);
    return normalize(origStr);
    }

    /**
    * Match the accented characters within a String choosing Canonical
    * Decomposition option of the Normalizer, regex replaceAll using non POSIX
    * character classes for ASCII
    *
    * @param accented
    * @return normalized String
    */
    private String normalize(String accented) {
    String normalized = Normalizer.normalize(accented, Normalizer.Form.NFD);
    normalized = normalized.replaceAll("[^\\p{ASCII}]", "");
    return normalized;
    }
    }

    使用普通 jaxb 启用此插件解码是将这些类打包到一个 jar 中,添加 /META-INF/services/com.sun.tools.xjc.Plugin jar 中的文件并将其放入您的构建路径中。
    /META-INF/services/com.sun.tools.xjc.Plugin jar 中的文件:

    enter image description here

    该文件内容如下:
    com.popofibo.plugins.jaxb.NormalizeElements

    如前所述,我将其打包在 jar 中,将它部署在我的 Eclipse 构建路径中,现在我遇到了运行 eclipse kepler with JDK 1.7 的问题。我是否收到此异常(消息):
    com.sun.tools.xjc.plugin Provider <my class> not a subtype

    因此,最好使用 ANT 生成类,如下 build.xml对迄今为止所做的工作是否公正:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <project name="SomeProject" default="createClasses">

    <taskdef name="xjc" classname="com.sun.tools.xjc.XJC2Task">
    <classpath>
    <pathelement
    path="C:/Workspace/jaxb-ri-2.2.7/jaxb-ri-2.2.7/lib/jaxb-xjc.jar" />
    <pathelement
    path="C:/Workspace/jaxb-ri-2.2.7/jaxb-ri-2.2.7/lib/jaxb-impl.jar" />
    <pathelement
    path="C:/Workspace/jaxb-ri-2.2.7/jaxb-ri-2.2.7/lib/jaxb2-value-constructor.jar" />
    <pathelement path="C:/Workspace/normalizeplugin_xjc_v0.4.jar" />
    </classpath>
    </taskdef>

    <target name="clean">
    <delete dir="src/com/popofibo/jaxb" />
    </target>

    <target name="createClasses" depends="clean">
    <xjc schema="res/some.xsd" destdir="src" package="com.popofibo.jaxb"
    encoding="UTF-8">
    <arg value="-normalize" />
    </xjc>
    </target>
    </project>

    我选择的展示这个规范化过程的模式是:
    <xs:element name="shiporder">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="Örderperson" type="xs:string"/>
    <xs:element name="Şhİpto">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="address" type="xs:string"/>
    <xs:element name="Çity" type="xs:string"/>
    <xs:element name="ÇoÜntry" type="xs:string"/>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    <xs:element name="İtem" maxOccurs="unbounded">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="title" type="xs:string"/>
    <xs:element name="note" type="xs:string" minOccurs="0"/>
    <xs:element name="qÜantity" type="xs:positiveInteger"/>
    <xs:element name="price" type="xs:decimal"/>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    <xs:attribute name="orderid" type="xs:string" use="required"/>
    </xs:complexType>
    </xs:element>

    </xs:schema>

    如您所见,我已经将参数和包设置为我想要生成我的类的位置,瞧 - 生成的工件中类、方法、变量的 ASCII 名称(我看到的唯一差距是 XML 注释这不会影响原因,但也很容易克服):

    enter image description here

    上面的屏幕截图显示名称已规范化并替换为它们的 ASCII对应物(要检查没有替换的情况,请参阅选项 2 中的屏幕截图)。

    选项 2 - 使用外部绑定(bind)文件

    要删除重音字符,您可以创建自定义绑定(bind)文件,并在生成类时使用它来绑定(bind)类和属性名称。引用: Creating an External Binding Declarations File Using JAXB Binding Declarations

    我拿了 中已经提到的 xsd选项 1 元素名称包含“重音”(非 ASCII)字符:

    如果我在不指定外部绑定(bind)的情况下生成类,则会得到以下输出:

    enter image description here !

    现在,如果我稍微更改绑定(bind)以生成我选择的类名和变量,我会写我的 binding.xml作为:
    <jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1">
    <jxb:globalBindings localScoping="toplevel" />

    <jxb:bindings schemaLocation="some.xsd">
    <jxb:bindings node="//xs:element[@name='Şhİpto']">
    <jxb:class name="ShipTo" />
    </jxb:bindings>
    <jxb:bindings node="//xs:element[@name='Örderperson']">
    <jxb:property name="OrderPerson" />
    </jxb:bindings>
    <jxb:bindings node="//xs:element[@name='Şhİpto']//xs:complexType">
    <jxb:class name="ShipToo" />
    </jxb:bindings>
    </jxb:bindings>

    </jxb:bindings>

    现在,当我通过指定绑定(bind)文件通过 eclipse 生成我的类时:

    enter image description here

    在接下来的步骤中,我选择我得到的包和绑定(bind)文件,

    enter image description here

    注意:如果你没有使用 eclipse 来生成你的类,你可能需要检查 xjc binding compiler out 以利用您的外部绑定(bind)文件。

    关于java - JAXB 将非 ASCII 字符转换为 ASCII 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21606248/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com