在JAXB或Xstream中,可以在unmarshall期间过滤出类型/值上的某些子元素

时间:2014-01-16 12:32:31

标签: java jaxb xstream

希望每个人都很好,快速提问,看看是否有人有任何反馈意见。

过去两天我在试验JaxB和Xstream。我基本上使用XML库来编组和从Java对象解组XML。现在这是一项非常简单的任务,我很快就开始工作了。但是,我想要解组到Java对象列表中的XML非常长,并且包含许多可以忽略的子元素,而不会放入java对象列表中。 例如,xml看起来类似于:

<?xml version="1.0" encoding="UTF-8"?>
<Tables>
    <Table1>
        <TYPE>Test1</TYPE>
        <DATE>2014-01-16</DATE>
        <FLAG>True</FLAG>
    </Table1>
    <Table1>
        <TYPE>Test2</TYPE>
        <DATE>2014-01-15</DATE>
        <FLAG>False</FLAG>
    </Table1>
    <Table1>
        <TYPE>Test1</TYPE>
        <DATE>2014-01-14</DATE>
        <FLAG>True</FLAG>
    </Table1>
</Tables>

所以我希望库遍历所有的xml元素并解组到目前为止工作的java对象列表中,但是当它迭代时我想添加额外的功能来检查Type和Flag元素值,如果TYPE值等于Test2和/或如果Flag值等于False则忽略此子元素,并且不将它包含在Java对象的完成列表中。有谁知道JaxB或Xstream是否可以实现这一目标?或者,任何人都可以建议更好的方法来实现这一点,这需要最少的代码和手动解析。

我一直在JaxB中查看ValidationEventHandler和XmlAdapter,但我不认为这些会让我做我想做的事。我接近Xmldapter但是unmarshal必须为它处理的每个xml子元素返回null或者一个对象,它还将xml语法改为属性形式,即TYPE =“Test1”等,我没有看到任何改变方式。

Xstream允许你实现一个具有canConvert方法的Converter,但是这只适用于Class类型,而不是我要检查每个子元素的子元素类型。看看可以在Xstream中重载的MapperWrapper wrapMapper方法,但是它只显示了元素属性名称,即FLAG并没有显示值,如果它确实显示了值,我也看不到告诉函数忽略子根元素以及所述孩子的所有属性。

无论如何,这是我的两分钱。有什么建议?

1 个答案:

答案 0 :(得分:2)

如果选择EclipseLink MOXy作为JAXB实现(而不是默认实现),则可以在Java类上使用注释来进行使用XPath表达式的解组。这可以用于过滤掉某些输入。这是链接:http://www.eclipse.org/eclipselink/moxy.php

或者,可能更简单的是,将XML转换API与样式表一起使用,该样式表具有过滤掉不需要的内容的模板。请检查类javax.xml.bind.util.JAXBResult,它允许您从一个源(例如InputStreamInputReader)直接转换为Java对象。可以把它想象成在中间使用变压器进行解组。

编辑: 我将为您提供一个基本的XSLT和一些代码。 这是你所描述的样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Table1[TYPE = 'Test1' or FLAG = 'True']">
        <!-- Don't do anything, since we want to filter these Table1 elements out -->
    </xsl:template>

</xsl:stylesheet>

可以作为基础的代码摘录:

//Obtain a TransformerFactory
//Obtain a Source for your stylesheet, like a StreamSource
Transformer transformer = transformerFactory.newTransformer(source);

//Next, create an Unmarshaller from a JAXBContext
Unmarshaller unmarshaller = context.createUnmarshaller();

//Create a JAXBResult with the Unmarshaller
JAXBResult result = new JAXBResult(unmarshaller);

//Obtain a Source for your input XML, and transform
transformer.transform(inputSource, result);

//Get the JAXBElement from the result
final JAXBElement<?> jaxbEl = (JAXBElement<?>)result.getResult();

//And now your unmarshalled Java bean from the JAXBElement
Object bean = jaxbEl.getValue();