【问题标题】:In JAXB or Xstream is it possible to Filter out certain Child Elements on Type/value during unmarshall在 JAXB 或 Xstream 中,是否可以在解组期间过滤掉类型/值上的某些子元素
【发布时间】:2014-01-16 12:32:30
【问题描述】:

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

在过去的两天里,我一直在试验 JaxB 和 Xstream。我基本上是使用 XML 库将 XML 编组到 Java 对象或从 Java 对象解组。现在这是一个非常简单的任务,我很快就开始工作了。但是,我要解组为 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 并且不显示值,如果它确实显示值,我也看不到告诉函数忽略子根元素以及所述孩子的所有属性。

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

【问题讨论】:

    标签: java jaxb xstream


    【解决方案1】:

    如果您选择 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();
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-14
    • 2019-01-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多