Java 如何使用ApacheDaffodil';s DataProcessor.unparse()方法来重新生成原始解析消息?

Java 如何使用ApacheDaffodil';s DataProcessor.unparse()方法来重新生成原始解析消息?,java,parsing,dfdl,Java,Parsing,Dfdl,我是阿帕奇水仙花的初学者 我使用Daffodil Java API成功地将输入文本消息解析为XML字符串,即 Compiler dfdlCompiler = Daffodil.compiler(); dfdlCompiler.setValidateDFDLSchemas(true); File schemaFile = this.getFileFromResources("EDIFACT-SupplyChain-D03B/EDIFACT-Suppl

我是阿帕奇水仙花的初学者

我使用Daffodil Java API成功地将输入文本消息解析为XML字符串,即

        Compiler dfdlCompiler = Daffodil.compiler();
        dfdlCompiler.setValidateDFDLSchemas(true);
        File schemaFile = this.getFileFromResources("EDIFACT-SupplyChain-D03B/EDIFACT-SupplyChain-Messages-D.03B.xsd");
        ProcessorFactory processorFactory = dfdlCompiler.compileFile(schemaFile);
        DataProcessor dataProcessor = processorFactory.onPath("/");
        java.io.File file = getFileFromResources("TestData/ORDERS_D.03B_Interchange.txt");
        java.io.FileInputStream fis = new java.io.FileInputStream(file);
        InputSourceDataInputStream dis = new InputSourceDataInputStream(fis);
        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
        ParseResult parseResult = dataProcessor.parse(dis, outputter);
        Document doc = outputter.getResult().getDocument();
        XMLOutputter xo = new XMLOutputter(org.jdom2.output.Format.getPrettyFormat());
        String xmlString = xo.outputString(doc);

        System.out.println("parsed text... resulting xmlString=" + xmlString);
但是,现在我还不清楚如何使用unparse()方法来重构原始文本消息(似乎缺少使用Daffodil的Java API来解析以重构原始消息的示例)

试一试:

        SAXBuilder builder = new SAXBuilder();
        Document d2 = builder.build(new StringReader(xmlString));
        JDOMInfosetInputter inputter = new JDOMInfosetInputter(d2);
        WritableByteChannel output = Channels.newChannel(new DataOutputStream(new ByteArrayOutputStream()));
        UnparseResult result = dataProcessor.unparse(inputter, output);
如何提取原始消息?或者,这种方法是否不正确

ApacheDaffodil版本:2.3

Java版本:jdk8+


使用这个略显精简的Java应用程序进行测试

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import org.jdom2.Document;
import org.jdom2.output.XMLOutputter;

import org.apache.daffodil.japi.Compiler;
import org.apache.daffodil.japi.Daffodil;
import org.apache.daffodil.japi.DataProcessor;
import org.apache.daffodil.japi.ParseResult;
import org.apache.daffodil.japi.ProcessorFactory;
import org.apache.daffodil.japi.UnparseResult;
import org.apache.daffodil.japi.infoset.JDOMInfosetInputter;
import org.apache.daffodil.japi.infoset.JDOMInfosetOutputter;
import org.apache.daffodil.japi.io.InputSourceDataInputStream;
import org.jdom2.input.SAXBuilder;

public class Blah2 {

    public static void main(String[] args) throws IOException, Exception {
        Blah2 b = new Blah2();
        b.process();
    }

    private void process() throws IOException, Exception {

        Compiler dfdlCompiler = Daffodil.compiler();
        dfdlCompiler.setValidateDFDLSchemas(true);
        File schemaFile = this.getFileFromResources("EDIFACT-SupplyChain-D03B/EDIFACT-SupplyChain-Messages-D.03B.xsd");
        ProcessorFactory processorFactory = dfdlCompiler.compileFile(schemaFile);
        DataProcessor dataProcessor = processorFactory.onPath("/");
        java.io.File file = getFileFromResources("TestData/ORDERS_D.03B_Interchange.txt");
        java.io.FileInputStream fis = new java.io.FileInputStream(file);
        InputSourceDataInputStream dis = new InputSourceDataInputStream(fis);
        JDOMInfosetOutputter outputter = new JDOMInfosetOutputter();
        ParseResult parseResult = dataProcessor.parse(dis, outputter);
        Document doc = outputter.getResult().getDocument();
        XMLOutputter xo = new XMLOutputter(org.jdom2.output.Format.getPrettyFormat());
        String xmlString = xo.outputString(doc);

        System.out.println("parsed text... resulting xmlString=" + xmlString);

        SAXBuilder builder = new SAXBuilder();
        Document d2 = builder.build(new StringReader(xmlString));
        JDOMInfosetInputter inputter = new JDOMInfosetInputter(d2);
        WritableByteChannel output = Channels.newChannel(new DataOutputStream(new ByteArrayOutputStream()));
        UnparseResult result = dataProcessor.unparse(inputter, output);

        System.out.println("unparsed xml document.. result.toString()=" + String.valueOf(result));        

        //how can I obtain the original input text???
    }

    private File getFileFromResources(String fileName) throws IOException {
        URL resource = this.getClass().getClassLoader().getResource(fileName);
        return new File(resource.getFile());
    }
}   
下面是解析操作的输出

(我仍然不明白我如何才能实现相反的目标——即“取消分析”)

解析文本。。。结果xmlString=
联阿办事处
4.
应用
1.
公司
1.
20051107
1159
6002
SSDD1
命令
D
03B
联合国
EAN008
BGM
2B33232302B424B4F4439392B39
数字地面模型
2B3133373A32305313130373A313032
纳德
2B42592B3534313233343533030303137363A3A339
纳德
2B53552B3430313233343533030303039343A3A39
CTA
2B4141
组件对象模型
2B73313A41412A7332313A41412A7333313A4141
林
2B312B312B312B3037363435363933130343A4942
数量
2B313A3235
FTX
2B41464D2B312B4C6F7264206F66207466865205269696E6773
林
2B322B312B312B3037363435363939303A4942
数量
2B313A3235
FTX
2B41464D2B312B54686520486F626974
林
2B332B312B312B3136310343635363A4942
数量
2B313A3136
FTX
2B41464D2B312B54686520536966C6D6172696C6C696F6E
林
2B342B312B312B303539363003637335363A4942
数量
2B313A3130
FTX
2B41464D2B312B546865204368696C6472656E206F66204875726966E
UNS
2B53
碳纳米管
2B323A34
22
SSDD1
1.
6002
未解析的xml文档。。result.toString()=org.apache.daffodil.japi。UnparseResult@2e734540

实际的
UnparseResult
actual不包含unparse的结果(是的,也许我们可以更好地命名它;)。
UnparseResult
实际上只包含解压是否成功(通过
isError
方法)以及出现故障时的任何诊断。unpasse数据被写入
WritableByteChannel
,作为参数传递到
unpasse()

问题在于,在您的情况下,您需要定义以下通道:

WritableByteChannel output=Channels.newChannel(新的DataOutputStream(新的ByteArrayOutputStream());
因此,您定义的通道通过tearrayoutputstream写入底层的
,但是您没有任何对这些字节的访问权限,因为它没有分配给变量。因此,您真正想要做的是将
ByteArrayOutputStream
分配给一个变量,并将其传递给新通道,然后在解压后访问字节数组——类似这样:

ByteArrayOutputStream boas=newbytearrayoutputstream();
WritableByteChannel输出=Channels.newChannel(新数据输出流(boas));
UnparseResult result=dataProcessor.unparse(输入、输出);
System.out.println(boas.toString());
此外,下面是我们的Java API测试,这是水仙花Java API使用的一些好资源:


其中有使用ByteArrayOutputStream和WritableByteChannel来解析字节并转换为字符串的示例。

我看到您打开
TestData/ORDERS\u D.03B\u Interchange.txt
并根据DFDL模式解析它
EDIFACT-SupplyChain-D03B/EDIFACT-SupplyChain-Messages-D.03B.xsd
。问:这是否为您提供了预期的XML?问:当您尝试“unpasse()”该XML文档时,会发生什么情况?你有什么发现吗?嗨,paulsm4-发布了输出。同样,我可以编译和解析w/o错误,但仍然不清楚如何完成反向操作,即“unpasse()”。感谢您的帮助/示例BTW-我正在使用GitHub上公开提供的UN/EDIFACT模式-以及示例消息THX,Steve!非常感谢你!:-)-不幸的是,boas.toString()的输出——即UNB+UNOA:4+应用程序:1+公司:1+20051107:1159+6002’——比原始消息短得多。还不知道为什么会这样。(正如我所指出的,当涉及水仙花(DFDL)加工时,我是一个超级新手)。我仍然会将您的标记为可接受的答案-因为我至少得到了一些我正在寻找的输出(原始消息)-在我什么都没有之前,如果您还没有,您可以尝试最近的2.4.0版。此版本大大提高了与上的许多架构(包括EDIFACT)的兼容性。如果这不能解决问题,您还可以尝试邮件列表()。调试模式问题有时可能需要多次往返时间,这通常在电子邮件上更容易做到。
parsed text... resulting xmlString=<?xml version="1.0" encoding="UTF-8"?>
<D03B:Interchange xmlns:D03B="http://www.ibm.com/dfdl/edi/un/edifact/SupplyChain/D03B">
  <UNB>
    <S001>
      <E0001>UNOA</E0001>
      <E0002>4</E0002>
    </S001>
    <S002>
      <E0004>APPLICATION</E0004>
      <E0007>1</E0007>
    </S002>
    <S003>
      <E0010>COMPANY</E0010>
      <E0007>1</E0007>
    </S003>
    <S004>
      <E0017>20051107</E0017>
      <E0019>1159</E0019>
    </S004>
    <E0020>6002</E0020>
  </UNB>
  <D03B:Message>
    <UNH>
      <E0062>SSDD1</E0062>
      <S009>
        <E0065>ORDERS</E0065>
        <E0052>D</E0052>
        <E0054>03B</E0054>
        <E0051>UN</E0051>
        <E0057>EAN008</E0057>
      </S009>
    </UNH>
    <D03B:BadMessage>
      <Segment>
        <Name>BGM</Name>
        <Data>2B3232302B424B4F4439392B39</Data>
      </Segment>
      <Segment>
        <Name>DTM</Name>
        <Data>2B3133373A32303035313130373A313032</Data>
      </Segment>
      <Segment>
        <Name>NAD</Name>
        <Data>2B42592B353431323334353030303137363A3A39</Data>
      </Segment>
      <Segment>
        <Name>NAD</Name>
        <Data>2B53552B343031323334353030303039343A3A39</Data>
      </Segment>
      <Segment>
        <Name>CTA</Name>
        <Data>2B4141</Data>
      </Segment>
      <Segment>
        <Name>COM</Name>
        <Data>2B7331313A41412A7332313A41412A7333313A4141</Data>
      </Segment>
      <Segment>
        <Name>LIN</Name>
        <Data>2B312B312B303736343536393130343A4942</Data>
      </Segment>
      <Segment>
        <Name>QTY</Name>
        <Data>2B313A3235</Data>
      </Segment>
      <Segment>
        <Name>FTX</Name>
        <Data>2B41464D2B312B2B4C6F7264206F66207468652052696E6773</Data>
      </Segment>
      <Segment>
        <Name>LIN</Name>
        <Data>2B322B312B303736343536393039303A4942</Data>
      </Segment>
      <Segment>
        <Name>QTY</Name>
        <Data>2B313A3235</Data>
      </Segment>
      <Segment>
        <Name>FTX</Name>
        <Data>2B41464D2B312B2B54686520486F62626974</Data>
      </Segment>
      <Segment>
        <Name>LIN</Name>
        <Data>2B332B312B313836313030343635363A4942</Data>
      </Segment>
      <Segment>
        <Name>QTY</Name>
        <Data>2B313A3136</Data>
      </Segment>
      <Segment>
        <Name>FTX</Name>
        <Data>2B41464D2B312B2B5468652053696C6D6172696C6C696F6E</Data>
      </Segment>
      <Segment>
        <Name>LIN</Name>
        <Data>2B342B312B303539363030363735363A4942</Data>
      </Segment>
      <Segment>
        <Name>QTY</Name>
        <Data>2B313A3130</Data>
      </Segment>
      <Segment>
        <Name>FTX</Name>
        <Data>2B41464D2B312B2B546865204368696C6472656E206F6620487572696E</Data>
      </Segment>
      <Segment>
        <Name>UNS</Name>
        <Data>2B53</Data>
      </Segment>
      <Segment>
        <Name>CNT</Name>
        <Data>2B323A34</Data>
      </Segment>
    </D03B:BadMessage>
    <UNT>
      <E0074>22</E0074>
      <E0062>SSDD1</E0062>
    </UNT>
  </D03B:Message>
  <UNZ>
    <E0036>1</E0036>
    <E0020>6002</E0020>
  </UNZ>
</D03B:Interchange>

unparsed xml document.. result.toString()=org.apache.daffodil.japi.UnparseResult@2e734540