ser*_*dar 5 java xsd locale jaxb
我有一些xsd模式,元素名称包含非ASCII字符.当我使用Eclipse Kepler 使用Generate JAXB Classes命令生成java类时 ,生成的类和变量包含非ASCII字符.我想将这个非ASCII字符转换为ASCII字符.
我已经在JAVA_TOOL_OPTIONS设置了语言环境
-Duser.country=GB -Duser.language=en
Run Code Online (Sandbox Code Playgroud)
例如
? -> I
Ç -> C
? -> S
Ö -> O
? -> G
Ü -> U
? -> i
ö -> o
ü -> u
ç -> c
? -> g
? -> s
Run Code Online (Sandbox Code Playgroud)
编辑: 由于要求是通用解决方案而不使用外部绑定文件,我提供了以下2个选项:
通用解决方案有效:
com.sun.tools.xjc.Plugin抽象类并覆盖JAXB用于命名工件的方法 - 基本创建插件jar专门调用jar内部文件夹services目录中的实现名称之后META-INFjaxblibs 一起部署并通过ANT运行它(build.xml下面提供,继续阅读)你的目的,我已经创造了它,你可以从下载JAR插件这里,下载ant脚本(build.xml从)这里.将jar放入eclipse中的构建路径并编辑ant文件以提供JAXB库的位置,生成的类的目标包,项目名称和模式位置并运行它. 而已!
说明:
我创建了一个XJC带有额外命令行选项的自定义插件,-normalize用于替换创建的Java类,方法,变量,属性和接口中的重音字符及其ASCII等价物.
XJC具有自定义插件创建功能,可以控制生成的类,变量等的名称,注释和其他属性.这篇博文虽然陈旧,但可以让您了解这些插件实现的基础知识.
长话短说,我创建了一个扩展抽象com.sun.tools.xjc.Plugin类的类,重写其重要的方法onActivated.
在这个方法中,我已经设置com.sun.tools.xjc.Option#setNameConverter了一个自定义类,它负责覆盖获取类,方法等名称所需的方法.我已经将源代码提交到我的git repo,下面是它的详细用法:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
要使用正常的jaxb解组启用此插件,请将这些类打包到jar中,在jar中添加/META-INF/services/com.sun.tools.xjc.Plugin文件并将其放入构建路径中.
/META-INF/services/com.sun.tools.xjc.Plugin jar中的文件:

该文件为:
com.popofibo.plugins.jaxb.NormalizeElements
Run Code Online (Sandbox Code Playgroud)
如前所述,我把它打包成一个jar,在我的eclipse构建路径中部署它,现在我遇到运行的问题eclipse kepler with JDK 1.7是我得到这个异常(消息):
com.sun.tools.xjc.plugin Provider <my class> not a subtype
Run Code Online (Sandbox Code Playgroud)
因此,使用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>
Run Code Online (Sandbox Code Playgroud)
展示我选择的规范化过程的模式是:
<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>
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我已经设置了参数和包,以确定我希望生成类的位置,并且瞧 - 生成的工件中的类,方法,变量的ASCII名称(我看到的唯一差距是XML注释)这不会影响原因,但也很容易克服):

上面的屏幕截图显示了名称已经标准化并被其ASCII对应的名称替换(要查看它没有替换的样子,请参阅选项2中的屏幕截图).
要删除重音字符,您可以创建自定义绑定文件,并在生成类时使用它绑定类和属性名称.请参阅:使用JAXB绑定声明创建外部绑定声明文件
我使用了选项1中已经提到的xsd ,其元素名称包含"重音"(非ASCII)字符:
如果我在没有指定外部绑定的情况下生成类,则会得到以下输出:
!
现在,如果我稍微更改绑定以生成我选择的类名和变量,我将我写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>
Run Code Online (Sandbox Code Playgroud)
现在,当我通过指定绑定文件通过eclipse生成我的类时:

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

注意:如果您没有使用eclipse生成类,则可能需要检查xjc绑定编译器以利用外部绑定文件.
| 归档时间: |
|
| 查看次数: |
1983 次 |
| 最近记录: |