java - 在 JAXB 或 Xstream 中,是否可以在解码期间过滤掉类型/值上的某些子元素

标签 java jaxb xstream

希望大家都好,快速提问看看是否有人有任何反馈。

过去两天我正在尝试 JaxB 和 Xstream。我基本上使用 XML 库将 XML 编码到 Java 对象或从 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 方法的转换器,但这仅适用于类类型,而不适用于我想要检查每个子元素的子元素类型。看看可以在 Xstream 中重载的 MapperWrapper wrapMapper 方法,但它只显示元素属性名称,即 FLAG 并且不显示值,而且如果它确实显示值,我也看不到告诉函数忽略子根元素以及该 child 的所有属性。

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

最佳答案

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

或者,可能更简单的是,将 XML 转换 API 与样式表一起使用,该样式表具有过滤掉不需要的内容的模板。请查看类(class)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();

关于java - 在 JAXB 或 Xstream 中,是否可以在解码期间过滤掉类型/值上的某些子元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21161881/

相关文章:

java - 如何更改 JSlider 的默认/起始值

java - 安卓下载镜像

java - WebServiceTemplate对象初始化一次后为null

java - 使用XStream读取XML对象时,如果我不知道XML有多少个字段怎么办?

Java 在循环期间暂停

java - 如何使用 JAXB XmlAdapter 来编码列表?

eclipse - JAXB 绑定(bind) XBRL 元素不起作用

java - XPath:以不同方式定义的节点

java - XStream - marshal/unmarshal 的不同别名?

java - android.view.InflateException : Binary XML file line #11: Binary XML file line #39: Error inflating class support. v4.view.ViewPager