我有一个XML格式的配置文件,类似于:
<configuration>
<database>
<host></host>
<port></port>
</database>
<queue>
<host></host>
<port></port>
<type></type>
</queue>
</configuration>
我想使用JAXB / xjc为此配置生成Java类,但是我想生成这些类并将这些类解组到树中。我不想接收Configuration.java,而是想要一个Database.java和Queue.java(为了将它们分别注入到Guice托管应用程序中)。我(目前)没有看到这样做的任何方式,但可能正在寻找错误的东西。
经过一些实验,我找到了一个生成这些类的解决方案,并能够根据类填充和返回这些类:
首先,我添加了一个bindings.xjb文件,该文件将生成包含的类(本例中为Database和Queue)
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:globalBindings localScoping="toplevel"/>
</jaxb:bindings>
但是,JAXB无法解组使用Database或Queue类,只能使用Configuration类(这可能是我可能遗漏的内容)。我能做到
JAXBContext context = JAXBContext.newInstance(Configuration.class);
Unmarshaller um = context.createUnmarshaller();
Configuration conf = (Configuration) um.unmarhal(xmlFile);
但不是
JAXBContext context = JAXBContext.newInstance(Database.class);
Unmarshaller um = context.createUnmarshaller();
Database db = (Database) um.unmarhal(xmlFile);
但是,因为我可以通过在Configuration对象的实例上调用getDatabase()来获取数据库对象,所以也可以使用反射使其成为通用的(使得此代码缓存结果在适当的位置是另一个练习):
T item = null;
try {
JAXBContext context = JAXBContext.newInstance(Configuration.class);
Unmarshaller um = context.createUnmarshaller();
Configuration conf = (Configuration) um.unmarshal(xmlFile);
Method[] allMethods = Configuration.class.getDeclaredMethods();
for (Method method : allMethods)
{
if (method.getReturnType().equals(clazz))
{
item = (T) method.invoke(conf);
break;
}
}
} catch (JAXBException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new ConfigException("Failure detected while loading configuration", e);
}
return item;
我不确定这是最好的解决方案(我昨天才开始使用JAXB),但似乎达到了我的目标。
答案 0 :(得分:0)
我正在用问题中讨论的问题解决方案来回答这个问题。这符合我的要求:
经过一些实验,我找到了一个生成这些类的解决方案,并能够根据类填充和返回这些类:
首先,我添加了一个bindings.xjb文件,该文件将生成包含的类(本例中为Database和Queue)
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:globalBindings localScoping="toplevel"/>
</jaxb:bindings>
但是,JAXB无法解组使用Database或Queue类,只能使用Configuration类(这可能是我可能遗漏的内容)。我能做到
JAXBContext context = JAXBContext.newInstance(Configuration.class);
Unmarshaller um = context.createUnmarshaller();
Configuration conf = (Configuration) um.unmarhal(xmlFile);
但不是
JAXBContext context = JAXBContext.newInstance(Database.class);
Unmarshaller um = context.createUnmarshaller();
Database db = (Database) um.unmarhal(xmlFile);
但是,因为我可以通过在Configuration对象的实例上调用getDatabase()来获取数据库对象,所以也可以使用反射使其成为通用的(使得此代码缓存结果在适当的位置是另一个练习):
T item = null;
try {
JAXBContext context = JAXBContext.newInstance(Configuration.class);
Unmarshaller um = context.createUnmarshaller();
Configuration conf = (Configuration) um.unmarshal(xmlFile);
Method[] allMethods = Configuration.class.getDeclaredMethods();
for (Method method : allMethods)
{
if (method.getReturnType().equals(clazz))
{
item = (T) method.invoke(conf);
break;
}
}
} catch (JAXBException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new ConfigException("Failure detected while loading configuration", e);
}
return item;
这允许我通过传递Database.class来获得一个解组数据库,而无需为任何配置参数硬编码方法。然后可以在需要的地方注入这些内容,而无需注入整个未编组的XML文件。
答案 1 :(得分:0)
步骤1:创建3个类configuration.java,database.java,queue.java
configuration.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "configuration")
public class configuration{
@XmlElement
private database db;
@XmlElement
private queue q;
...
}
@XmlAccessorType(XmlAccessType.FIELD)
public class database{
@XmlElement
private String host;
@XmlElement
private String port;
....
}
-------------------------
InputStream xmlStream = new FileInputStream(config.xml);
JAXBContext jaxbContext = JAXBContext.newInstance(configuration.class, database.class,queue.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
configuration config= (configuration) jaxbUnmarshaller.unmarshal(xmlStream);
config.getDatabase().getHost(); //returns the host
config.getDatabase().getPort(); //returns the port
------------------------------------