如何从相互引用的XML标记创建Java对象?

时间:2022-02-10 08:45:14

I have an XML which has tags corresponding to three types of Java objects which would be created from the XML. The objects are of the form:

我有一个XML,它有与三种类型的Java对象相对应的标记,这些标记将从XML创建。对象的形式如下:

A
- static Map<String, A>
- String name
- String aInfo1
- String aInfo2

B
- static Map<String, B>
- String name
- String bInfo1
- String bInfo2

C
- A aObject
- B bObject

Now, in my XML, I define a list of tags for A objects and B objects and then I define tags for C objects which refer to A and B objects using there name field. I have two requirements:

现在,在我的XML中,我为A对象和B对象定义了一个标签列表,然后我为C对象定义了标签,这些对象使用name字段引用A和B对象。我有两个要求:

  1. populate static maps in A and B while reading the A and B objects from XMLs. The maps will contain a mapping of A.name to A, and B.name to B respectively.
  2. 在从XML读取A和B对象时填充A和B中的静态映射。这些映射将包含A.name到A的映射,以及B.name到B.的映射。
  3. populate C objects by reading the A.name and B.name from XML tag and then using the maps defined in A and B objects.
  4. 通过从XML标记读取A.name和B.name然后使用A和B对象中定义的映射来填充C对象。

I have read about some Java frameworks like JAXB but I am unable to come up with a way to create such type of objects from my XML. Is there a framework in Java which can do this out-of-the box or with minimum logic?

我已经阅读了一些像JAXB这样的Java框架,但是我无法想出一种从我的XML创建这种类型的对象的方法。 Java中是否有一个可以开箱即用或者逻辑最少的框架?

Edit:

编辑:

There is another requirement: I need to define D and E objects of the form

还有另一个要求:我需要定义表单的D和E对象

D
- Map<A, E>

I would define E objects similar to how servlets are defined in web.xml i.e. first define the name and class for the E class and then use the name for E at some other place. Additionally, pass parameters to instantiate E objects. The tag would look like:

我将定义E对象,类似于在web.xml中定义servlet的方式,即首先定义E类的名称和类,然后在其他地方使用E的名称。另外,传递参数以实例化E对象。标签看起来像:

<E>
    <name>queryProcessor</name>
    <class>com.mydomain.QueryProcessor</class>
</E>

Now this would be used while defining content of Map in D

现在,这将在定义D中的Map内容时使用

<D>
    <map>
        <A>name_of_some_A_object</A>
        <E name="queryProcessor">
            <param1>name_of_some_B_object</param1>
            <param2>name_of_some_B_object</param2>
        </E>
        <A>name_of_some_A_object</A>
        <E name="queryProcessor">
            <param1>name_of_some_B_object</param1>
            <param2>name_of_some_B_object</param2>
        </E>
     </map>
 </D>

Essentially the map in D will be populated by instantiating a class of base type E with the parameters passed to it and an object of A, referred by its name.

本质上,D中的映射将通过实例化一个基类型E的类来填充,其中传递给它的参数和由其名称引用的A的对象。

3 个解决方案

#1


3  

  • Specify the correct XML format with an XSD
  • 使用XSD指定正确的XML格式
  • Generate the JAXB classes
  • 生成JAXB类

(You could do it also the other way around, if you are familiar with JAXB annotations and want to control the interface with Java rather than with an XSD).

(如果您熟悉JAXB注释并希望使用Java而不是XSD控制接口,那么您也可以反过来这样做。

Note: static Maps is most likely not what you want to use. If you explain more about what problem you want to solve we might be able to point you out some alternative ways

注意:静态地图很可能不是您想要使用的。如果您解释更多关于您想要解决的问题,我们可能会指出一些替代方法

Edit:

编辑:

Are you talking about the format of the XML? Or why I need XML at all? I need XML for the ability to make my applications configurable outside of Java.

你在谈论XML的格式吗?或者为什么我需要XML呢?我需要XML才能使我的应用程序在Java之外进行配置。

It looks like you're re-inventing the wheel. Have a look at Spring and see if it fits your needs. If it doesn't, explain why.

看起来你正在重新发明*。看看Spring,看看它是否符合您的需求。如果没有,请解释原因。

#2


1  

From what you describe this could be done with a common framework such as Spring, either by you changing your XML or generate a XSTL which creates a Spring XML config file from your XML.

根据您的描述,这可以通过一个常见的框架(如Spring)来完成,可以通过更改XML或生成XSTL来创建XML XML配置文件。

Spring Core documentation is probably enough to get you started. An example of the XML would be

Spring Core文档可能足以让您入门。 XML的一个例子是

<bean id="beanOneId" class="the.bean.Class">
    <property name="someProperty" value="staticValue">
    <property name="someOtherProperty" ref="beanTwoId">
</bean>
<bean id="beanTwoId" class="the.otherbean.Class">
    <property name="someOtherProperty" ref="beanOneId">
    <property name="someOtherProperty" ref="beanThreeId">
</bean>

But what you describe should not be too hard with reflection. Assuming that none of the other objects need a reference in the constructor (but rather as setX) I would start by scanning the xml, create and store all objects with their names and remember a list of "connections" so be made. After all objects are created do all connections in the connection list.

但你所描述的不应该用反思太难。假设其他对象都不需要构造函数中的引用(而是作为setX),我将首先扫描xml,创建并存储所有对象及其名称,然后记住一个“连接”列表。创建所有对象后,请在连接列表中执行所有连接。

#3


1  

Maybe you want to have a look at XStream: http://x-stream.github.io/

也许你想看看XStream:http://x-stream.github.io/

It is a good library to marshal and unmarshal objects to and from XML, and does nothing more (unlike Spring). Like example in http://x-stream.github.io/tutorial.html, You can load objects from XML as easy as:

它是一个很好的库,用于编组和解组XML中的对象,并且不做任何事情(与Spring不同)。与http://x-stream.github.io/tutorial.html中的示例一样,您可以像以下一样轻松地从XML加载对象:

Person newJoe = (Person)xstream.fromXML(xml);

In order for XStream to understand your XML, you need to setup some alias like http://x-stream.github.io/alias-tutorial.html described.

为了让XStream理解您的XML,您需要设置一些别名,如http://x-stream.github.io/alias-tutorial.html所描述的。

XStream alone will not be able to solve your problem completely, mainly due to the two static maps. However you can let XStream to load a list of As and Bs from the XML, then build the two maps from the list.

单独的XStream将无法完全解决您的问题,主要是由于两个静态地图。但是,您可以让XStream从XML加载As和B的列表,然后从列表中构建两个映射。

For object C referencing A and B, you can read the following tutorial talking about object reference: http://x-stream.github.io/graphs.html. If it does not suit your need, you can always easily build another Class to read necessary information from XML using XStream, like

对于引用A和B的对象C,您可以阅读以下有关对象引用的教程:http://x-stream.github.io/graphs.html。如果它不适合您的需要,您可以随时轻松地构建另一个类,以使用XStream从XML读取必要的信息,例如

public class CInfo {
    public String aName;
    public String bName
}

And construct C instances using CInfo. Given you already have name to instance map of A and B, it will be trivial.

并使用CInfo构造C实例。鉴于你已经有了A和B实例图的名称,这将是微不足道的。

#1


3  

  • Specify the correct XML format with an XSD
  • 使用XSD指定正确的XML格式
  • Generate the JAXB classes
  • 生成JAXB类

(You could do it also the other way around, if you are familiar with JAXB annotations and want to control the interface with Java rather than with an XSD).

(如果您熟悉JAXB注释并希望使用Java而不是XSD控制接口,那么您也可以反过来这样做。

Note: static Maps is most likely not what you want to use. If you explain more about what problem you want to solve we might be able to point you out some alternative ways

注意:静态地图很可能不是您想要使用的。如果您解释更多关于您想要解决的问题,我们可能会指出一些替代方法

Edit:

编辑:

Are you talking about the format of the XML? Or why I need XML at all? I need XML for the ability to make my applications configurable outside of Java.

你在谈论XML的格式吗?或者为什么我需要XML呢?我需要XML才能使我的应用程序在Java之外进行配置。

It looks like you're re-inventing the wheel. Have a look at Spring and see if it fits your needs. If it doesn't, explain why.

看起来你正在重新发明*。看看Spring,看看它是否符合您的需求。如果没有,请解释原因。

#2


1  

From what you describe this could be done with a common framework such as Spring, either by you changing your XML or generate a XSTL which creates a Spring XML config file from your XML.

根据您的描述,这可以通过一个常见的框架(如Spring)来完成,可以通过更改XML或生成XSTL来创建XML XML配置文件。

Spring Core documentation is probably enough to get you started. An example of the XML would be

Spring Core文档可能足以让您入门。 XML的一个例子是

<bean id="beanOneId" class="the.bean.Class">
    <property name="someProperty" value="staticValue">
    <property name="someOtherProperty" ref="beanTwoId">
</bean>
<bean id="beanTwoId" class="the.otherbean.Class">
    <property name="someOtherProperty" ref="beanOneId">
    <property name="someOtherProperty" ref="beanThreeId">
</bean>

But what you describe should not be too hard with reflection. Assuming that none of the other objects need a reference in the constructor (but rather as setX) I would start by scanning the xml, create and store all objects with their names and remember a list of "connections" so be made. After all objects are created do all connections in the connection list.

但你所描述的不应该用反思太难。假设其他对象都不需要构造函数中的引用(而是作为setX),我将首先扫描xml,创建并存储所有对象及其名称,然后记住一个“连接”列表。创建所有对象后,请在连接列表中执行所有连接。

#3


1  

Maybe you want to have a look at XStream: http://x-stream.github.io/

也许你想看看XStream:http://x-stream.github.io/

It is a good library to marshal and unmarshal objects to and from XML, and does nothing more (unlike Spring). Like example in http://x-stream.github.io/tutorial.html, You can load objects from XML as easy as:

它是一个很好的库,用于编组和解组XML中的对象,并且不做任何事情(与Spring不同)。与http://x-stream.github.io/tutorial.html中的示例一样,您可以像以下一样轻松地从XML加载对象:

Person newJoe = (Person)xstream.fromXML(xml);

In order for XStream to understand your XML, you need to setup some alias like http://x-stream.github.io/alias-tutorial.html described.

为了让XStream理解您的XML,您需要设置一些别名,如http://x-stream.github.io/alias-tutorial.html所描述的。

XStream alone will not be able to solve your problem completely, mainly due to the two static maps. However you can let XStream to load a list of As and Bs from the XML, then build the two maps from the list.

单独的XStream将无法完全解决您的问题,主要是由于两个静态地图。但是,您可以让XStream从XML加载As和B的列表,然后从列表中构建两个映射。

For object C referencing A and B, you can read the following tutorial talking about object reference: http://x-stream.github.io/graphs.html. If it does not suit your need, you can always easily build another Class to read necessary information from XML using XStream, like

对于引用A和B的对象C,您可以阅读以下有关对象引用的教程:http://x-stream.github.io/graphs.html。如果它不适合您的需要,您可以随时轻松地构建另一个类,以使用XStream从XML读取必要的信息,例如

public class CInfo {
    public String aName;
    public String bName
}

And construct C instances using CInfo. Given you already have name to instance map of A and B, it will be trivial.

并使用CInfo构造C实例。鉴于你已经有了A和B实例图的名称,这将是微不足道的。