5

我正在寻找使用EXIficientOpenEXI编码/解码EXI(高效 XML 交换)流的 Java 示例程序。

有人可以帮忙吗?我似乎找不到示例应用程序。

编辑:或者,如果有人可以向我指出允许我使用 EXIficient 或 OpenEXI 的文档,那将很有帮助。我找到了 javadoc,但我不知道要使用哪些类。

或者,正如@StaxMan 指出的那样,是否特别提到/讨论了与标准 XML API 之一一起使用的适当顶级类?

4

5 回答 5

4

使用Exificient,我设法使用他们的“帮助”页面他们的“演示”中的片段将示例 XML 编码和解码为 EXI ,我已经设法仅使用 Maven 依赖项来完成以下工作

<dependency>
    <groupId>com.siemens.ct.exi</groupId>
    <artifactId>exificient</artifactId>
    <version>0.9.4</version>
</dependency>

用代码

import com.siemens.ct.exi.EXIFactory;
import com.siemens.ct.exi.GrammarFactory;
import com.siemens.ct.exi.api.sax.EXIResult;
import com.siemens.ct.exi.api.sax.EXISource;
import com.siemens.ct.exi.helpers.DefaultEXIFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;


// based on: https://sourceforge.net/p/exificient/code/HEAD/tree/tags/exificient-0.9.4/src/sample/java/EXIficientDemo.java?format=raw
public class MinimalistExificientSample {

    static final boolean USE_SCHEMA = true;

    public static void main(String[] args) throws Exception{
        File xmlIn  = new File( "/home/artb/spring-core-4.1.6.RELEASE.pom.xml" );
        FileInputStream xmlIns = new FileInputStream( xmlIn );

        File exi = new File( "/home/artb/spring-core-4.1.6.RELEASE.pom." +(USE_SCHEMA? "schema":"schemaless")+  ".exi" )
        FileOutputStream exiOuts = new FileOutputStream( exi );

        File xmlOut  = new File( "/home/artb/spring-core-4.1.6.RELEASE.pom." +(USE_SCHEMA? "schema":"schemaless")+ ".xml" );

        //settings
        EXIFactory exiFactory = DefaultEXIFactory.newInstance();
        exiFactory.setGrammars( GrammarFactory.newInstance().createGrammars( "/home/artb/maven-4.0.0.xsd" ) );

        // encode
        InputSource xmlIs = new InputSource( xmlIns );
        EXIResult exiResult = USE_SCHEMA ? new EXIResult(exiFactory) : new EXIResult();
        exiResult.setOutputStream( exiOuts );
        XMLReader xmlReader = XMLReaderFactory.createXMLReader();
        xmlReader.setContentHandler( exiResult.getHandler() );
        xmlReader.parse( xmlIs );

        // decode
        FileOutputStream xmlOuts = new FileOutputStream( xmlOut );
        FileInputStream exiIns = new FileInputStream( exi );
        InputSource exiIs = new InputSource( exiIns );
        EXISource exiSource = USE_SCHEMA ? new EXISource(exiFactory) : new EXISource();
        exiSource.setInputSource(exiIs);
        exiSource.setXMLReader( exiSource.getXMLReader() );
        TransformerFactory.newInstance().newTransformer().transform(exiSource, new StreamResult(xmlOuts));
    }

}

使用来自 Maven 中心的Maven XSDSpring 4.1.6 POM作为示例数据。

注意:输出 XML 应该等同于输入,但不一定相等,因为注释和空格丢失了,并且命名空间别名(?可能在这里使用了错误的术语)是任意分配的。

于 2015-07-08T01:21:08.367 回答
2

我不熟悉提到的两个库;但我认为,与任何健全的 XML 库一样,它们实现了众所周知的 Java XML 处理 API 之一,例如 SAX、Stax 或 DOM(可能带有一些扩展)。这是因为 EXI 只是标准 XML Infoset 的不同编码;所以对于应用程序开发人员来说,事情可能看起来与正常的 XML 处理完全一样。

那么,您可能只需要弄清楚他们实现的 API 并找到使用该 API 的教程?

于 2011-06-30T23:30:43.810 回答
0

OpenEXI 现在提供了关于如何使用它进行编程的教程 [1]。

[1] http://openexi.sourceforge.net/tutorial/

此外,这个 OpenEXI 论坛帖子 [2] 显示了使用“EXIReader”SAX XMLReader 实现从二进制 XML 转换为 (JaXB) Java 对象的代码:

[2] http://sourceforge.net/p/openexi/discussion/800031/thread/3103260f/?limit=50#2191

于 2012-03-06T06:55:27.603 回答
0

EXIfiecient 代码库中有一些单元测试可以用作示例。

于 2011-06-30T21:49:24.040 回答
0

下面总结了使用 OpenEXI 的方法,其中第 2 步和第 3 步是可选的。

  1. 使用 org.openexi.fujitsu.scomp 包中的 EXISchemaFactory 将 XML Schema 转换为 EXISchema。
  2. 将 EXISchema 序列化为文件。
  3. 从文件加载 EXISchema。
  4. 通过将 EXISchema 指定给构造函数来实例化 org.openexi.fujitsu.proc.grammars 包中的 GrammarCache。
  5. 在 org.openexi.fujitsu.sax 包中实例化 Transmogrifier,并使用 setEXISchema(grammarCache) 方法设置 GrammarCache。
  6. 通过调用 encode(InputSource is) 方法将 XML 文档编码为 EXI。
  7. 使用 org.openexi.fujitsu.proc 中的 EXIDecoder 将 EXI 解码为事件。实例化 EXIDEcoder 后,将 GrammarCache 和 InputStream 设置为它。调用 processHeader() 会返回一个 Scanner,而 Scanner 允许您在 EXI 中导航。只需在 Scanner 上调用 nextEvent() 即可获取下一个事件,直到它最终返回 null。

如果不使用模式,则可以在上面实例化 GrammarCache 时使用 null。

如果您有任何问题,请告诉我。

于 2011-07-01T16:56:22.927 回答