Java 向源自XSD的JAXB生成的类集合添加访问例程
我有一个基于XSD的嵌套XML结构。我使用JAXB进行只读解组 通常,我需要在大型结构的某处找到一个或多个元素。为了避免每次需要搜索时都遍历结构,我想添加一个带有内部缓存的优化搜索函数 定义它的最佳方式是什么?不同方式的利弊是什么 我最初考虑使用facade或adapter,adaper类在其中访问生成的类并根据需要添加方法;不过,我想征求一些建议 作为一个稍微简化的示例,需要在基于此XSD的XML中搜索具有特定boq元素的step类型的元素:Java 向源自XSD的JAXB生成的类集合添加访问例程,java,jaxb,adapter,delegation,facade,Java,Jaxb,Adapter,Delegation,Facade,我有一个基于XSD的嵌套XML结构。我使用JAXB进行只读解组 通常,我需要在大型结构的某处找到一个或多个元素。为了避免每次需要搜索时都遍历结构,我想添加一个带有内部缓存的优化搜索函数 定义它的最佳方式是什么?不同方式的利弊是什么 我最初考虑使用facade或adapter,adaper类在其中访问生成的类并根据需要添加方法;不过,我想征求一些建议 作为一个稍微简化的示例,需要在基于此XSD的XML中搜索具有特定boq元素的step类型的元素: <?xml version="1.0" en
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="test">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="group"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="group">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="step"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="step">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="number"/>
<xs:element ref="name"/>
<xs:element ref="type"/>
<xs:element ref="target"/>
<xs:sequence minOccurs="0">
<xs:element ref="boq"/>
<xs:element ref="remote"/>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="number" type="xs:integer"/>
<xs:element name="name" type="xs:NCName"/>
<xs:element name="type" type="xs:NCName"/>
<xs:element name="target" type="xs:NCName"/>
<xs:element name="boq" type="xs:string"/>
<xs:element name="remote" type="xs:string"/>
</xs:schema>
该模式是使用JAXB编译的,因此我得到了几个类。
使用解组功能,我在内存中拥有访问XML的数据结构
现在考虑一下,我需要一个优化的搜索函数,它访问定义了boq元素的所有步骤,并返回boq和remote的值(如果也定义了)
HashMap<String,Step> resultMap = new HashMap<>();
test.getGroup().forEach(group ->
group.getStep().forEach(step -> {
if ("searchpattern".equals(step.getBoq()))
resultMap.put("searchpattern", step);
}));
封装这种搜索的最佳方法是什么?我可以编写第二个类作为包含此方法的适配器,或者有更好的选项吗?遗产使用JAXB本身的选项?使用第三方插件,如用于maven的jaxb代理插件?有许多选项可以解决这个问题 实用类 最简单的方法是在实用程序类中简单地实现访问路由。所以,基本上您将调用SearchPatterns.offoo之类的函数,并向其传递一个模式派生类的实例。将其与foo.getSearchPatterns(其中getSearchPatterns以某种方式添加到模式派生类中)进行比较,差别并不大。好吧,好吧,不管怎么说都没那么糟糕,但是,坦率地说,谁在乎呢 使用代码注入器插件 您可以使用XJC代码注入器插件在生成的类中注入任何代码。有关示例,请参见以下问题: 如果你有问题,请问另一个问题。我意识到我们没有去XJC代码注入器的问题 这对您来说相对容易,并且允许您注入任何您想要的代码 缺点是部分Java代码将驻留在一个奇怪的XML文件中 扩展准备好的抽象类 另一种选择是使用所需的访问器方法准备一个抽象类,比如说getSearchpatterns以及它使用getGroup作为抽象方法的方法。然后让您的模式派生类扩展这个准备好的抽象类。生成的方法将实现在准备好的超类中定义的抽象方法。这本质上是一个模板方法模式 有许多方法可以使模式派生类扩展现有类。这是其中之一: 或者您也可以使用来自的继承插件。免责声明:我是作者 您可以使用模板方法+默认方法为访问器定义一个接口,并让您的模式派生类实现它,而不是扩展类 我不喜欢这个选项,因为它只是滥用继承来添加实用程序方法 编写自己的XJC插件 在要添加的访问器后面可能有一些特定的逻辑。因此,也许您不需要像使用代码注入器插件那样简单地注入代码,而是可以根据特定的逻辑实际生成访问器 然而,这是一个非常复杂的方法。有关简要概述,请参阅。如果真的有特定的逻辑,我才会接受 正式建议 我个人更喜欢将业务逻辑与模式派生类分开。我可能是那边最大的JAXB/XJC粉丝之一。我肯定会编写一个实用程序类,它提供您想要的任何访问器 我不喜欢代码注入器选项,因为这样您的部分代码就会出现在一些奇怪的XML文件中。因此,如果您要重构IDE中的任何东西,那么这些代码就不会被触及 扩展准备好的抽象类或实现准备好的接口也不是我最喜欢的。我认为这只是滥用OOP结构来添加一些实用程序代码
编写自己的插件对于没有太多XJC插件经验的开发人员来说太复杂了。此外,我无法识别可以以某种方式概括的特定逻辑,因此此选项可能根本没有意义。请发布一个您想要生成的代码示例。有几种方法可以解决这个问题,但您只能在个案的基础上对其进行合理的评估。这足够了吗,或者我应该进一步改进它吗?请发布一个您想要生成的代码示例。如何访问定义了boq元素的所有步骤,并返回boq和remote的值,就像在Java中一样?添加了我的访问例程。为什么要在模式派生类本身中使用此访问器代码?基本上,为什么是foo.getSearchPat terns vs SearchPatterns.offoo其中SearchPatterns是一个独立的实用程序类?