我是JAXB的新手,所以我不确定我想做的事情是否可能。
我有一个XML文件,基本上是为我的程序配置一些运行参数。某些配置共享大量相同的参数,只有1或2个参数不同。所以我的XML现在看起来像这样:
<Parameters id="1">
<Attribute1>value1<Attribute1>
<Attribute2>value2<Attribute2>
<Attribute3>value3<Attribute3>
<Attribute4>value4<Attribute4>
<Attribute5>value5<Attribute5>
</Parameters>
<Parameters id="2">
<Attribute1>value1<Attribute1>
<Attribute2>value2<Attribute2>
<Attribute3>value3<Attribute3>
<Attribute4>otherValue4<Attribute4>
<Attribute5>otherValue5<Attribute5>
</Parameters>
我正在寻找一种减少冗余的方法,这样我就有了一个基本配置,然后扩展,在扩展中,我只需要配置不同的参数。
<Parameters id="1">
<Attribute1>value1<Attribute1>
<Attribute2>value2<Attribute2>
<Attribute3>value3<Attribute3>
</Parameters>
<Parameters id="2" parent="1">
<Attribute4>value4<Attribute4>
<Attribute5>value5<Attribute5>
</Parameters>
<Parameters id="3" parent="1">
<Attribute4>otherValue4<Attribute4>
<Attribute5>otherValue5<Attribute5>
</Parameters>
值得一提的是,父节点的属性集对于不同的配置组不是固定的,也就是说,在其他情况下,属性1可能是正在改变的。JAXB有可能做到这一点吗?
我猜我对问题场景的最初描述有点不清楚/遗漏了一些细节。
我的参数设置是同一个根节点下一个xml文件中的所有单个节点。我使用XPATH检索单个参数节点,并将此节点散集到一个参数对象中。
到目前为止还不错,但是我现在想做的是通过使用某种继承来重组我的xml来减少冗余。例如,当加载id="2"的节点时,我希望我的参数对象继承id="1"的节点的值。
我对这个问题的解决方法分为两个简单的步骤。在第一步中,我只是从XML节点加载对象。然后检查节点是否有指定的parentId。如果是这种情况,我还为父对象加载对象,并将fiedl值复制到子对象(如果尚未设置)。
public static Parameters createParams(String id){
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(new File("src/test.xml"));
XPath xPath = XPathFactory.newInstance().newXPath();
JAXBContext jc = JAXBContext.newInstance(Parameters.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Node n = (Node) xPath.compile("/config/Parameters[@id='"+id+"']").evaluate(xmlDocument, XPathConstants.NODE);
Parameters p = (Parameters) unmarshaller.unmarshal(n);
if(p.parentId != null)
p.loadValuesFromParent(createParams(p.parentId));
return p;
}
public void loadValuesFromParent(Parameters parent) throws IllegalArgumentException, IllegalAccessException{
for (Field field : Parameters.class.getDeclaredFields()) {
if(field.get(this)==null){
field.set(this,field.get(parent));
}
}
}
根据我的评论,这可以通过任何简单的pojo实现,除非问题中缺少一些特别的东西。
样品pojo与主。
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement()
@XmlAccessorType(XmlAccessType.FIELD)
public class Parameters {
@XmlAttribute
private String id;
@XmlAttribute
private String parent;
@XmlElement(name = "Attribute1")
private String attribute1;
@XmlElement(name = "Attribute2")
private String attribute2;
@XmlElement(name = "Attribute3")
private String attribute3;
@XmlElement(name = "Attribute4")
private String attribute4;
@XmlElement(name = "Attribute5")
private String attribute5;
public static void main(String[] args) throws Exception{
JAXBContext jc = JAXBContext.newInstance(Parameters.class);
Marshaller marrshaller = jc.createMarshaller();
marrshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
Parameters p1 = new Parameters();
p1.id="1";
p1.attribute1="value1";
p1.attribute2="value2";
p1.attribute3="value3";
marrshaller.marshal(p1, System.out);
p1 = new Parameters();
p1.id="2";
p1.parent="1";
p1.attribute4="value4";
p1.attribute5="value5";
marrshaller.marshal(p1, System.out);
p1 = new Parameters();
p1.id="3";
p1.parent="1";
p1.attribute4="Othervalue4";
p1.attribute5="othervalue5";
marrshaller.marshal(p1, System.out);
}
}
和三个xml输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parameters id="1">
<Attribute1>value1</Attribute1>
<Attribute2>value2</Attribute2>
<Attribute3>value3</Attribute3>
</parameters>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parameters parent="1" id="2">
<Attribute4>value4</Attribute4>
<Attribute5>value5</Attribute5>
</parameters>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parameters parent="1" id="3">
<Attribute4>Othervalue4</Attribute4>
<Attribute5>othervalue5</Attribute5>
</parameters>
我目前正在尝试使用JaxB,但对于一个相对简单的示例,我并不是很成功。我的示例如下: 我所有的尝试(甚至编组)都失败了。我浏览了BlaiseDoughan的博客,包括http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html但他们似乎对我的例子都没有帮助。我很可能误用了他的例子。在我看来,我的示例应该是JaxB中
问题内容: 在JavaScript中,每个对象同时是一个实例和一个类。要进行继承,可以将任何对象实例用作原型。 在Python,C ++等中,有类和实例作为单独的概念。为了进行继承,您必须使用基类创建一个新类,然后可以使用该新类来生成派生实例。 为什么JavaScript朝这个方向发展(基于原型的面向对象)?与传统的基于类的OO相比,基于原型的OO有哪些优点和缺点? 问题答案: 这里大约有一百个术
问题内容: 我有一个自定义返回的我想将它作为任意XML包含在JAXB对象中(我知道我必须手工制作XSD)。但是,JAXB抱怨 显然,不支持将w3c XML类型作为Java类型来支持,这很遗憾。但是,除此之外,使用明显受到支持的错误时,我会遇到相同的错误。 如何在JAXB中包括任意XML元素作为元素? 注意:根据https://forums.oracle.com/thread/1668210我也尝试
问题内容: 我有两节课: 我想将类B编组为xml元素,并添加类A的属性fieldOfClassB和fieldOfClassA,但在编组期间会显示以下警告消息: 请注意,这两个类来自两个不同的程序包,我无法更改此对象模型。 先感谢您! 编辑: 我正在使用外部绑定文件。 问题答案: 从您发布的日志消息中,我可以看到您正在使用MOXy的外部映射文档(请参阅http://blog.bdoughan.com
要使用本节中描述的AOP命名空间标记,您需要按照描述导入springAOP模式 - <?xml version = "1.0" encoding = "UTF-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-insta
问题内容: 是否可以使用JAXB根据xml的属性将xml解组到特定的Java类? 我想要一个包含三角形和正方形的Shape对象的列表,每个对象都有自己的特定于形状的属性。IE浏览器: 我目前只是将所有属性都放在一个大的“ Shape”类中,这并不理想。 如果形状已正确命名为xml元素,则可以使它正常工作,但是不幸的是,我无法控制要检索的xml。 谢谢! 问题答案: JAXB是一个规范,特定的实现将