【问题标题】:need help to convert XML/Java to edi(834) document需要帮助将 XML/Java 转换为 edi(834) 文档
【发布时间】:2014-09-08 12:13:54
【问题描述】:

我们有许多 java 库,将 edi 解析为 XML,例如Smooks、ediParser 等。

我的用例有点不同。我需要将 XML 转换为 edi 文件。我没有找到任何将 XML 转换为 Java 的开源代码。

Smooks 文档描述了这种支持(xml->edi)(http://www.smooks.org/mediawiki/index.php?title=Main_Page),但没有解释。

请指导我如何将 xml 转换为 edi。

【问题讨论】:

  • "请指导我如何将 xml 转换为 edi" - 使用翻译器。那里有这么多高质量的应用程序。为什么一定要开源?
  • Andrew,请提供一些应用程序的参考,这些应用程序提供 xml->edi 转换。任何示例都会有很大帮助。
  • 任何通用数据转换器(任何到任何)都将提供您正在寻找的内容,并且能够集成到当前的应用程序中,有些翻译器比其他翻译器更好。如果您想进一步讨论,请随时通过我的个人资料与我联系。

标签: java xml edi


【解决方案1】:

几个选项。

  • XML DOM(文档对象模型)。 java提供的org.w3c.Document就足够了。然后您需要编写大量代码将每个元素写入 EDI。容易出错,容易忘记而且乏味。
  • java 中的模型类。反映 XML 元素的 Java 类。使用 JAXB 加载和保存。您可以对 XML 元素和属性名称使用注释。
  • 使用 XSLT 将 XML 转换为另一种文本格式。只有在 XML 和 EDI 之间几乎一一对应的情况下才合适。优点是它完全是声明性的。缺点是在 XSL 中不容易快速开发。

也许一个实用的解决方案是使用 XSLT 将 XML 转换为 EDI 记录加上额外的控制信息,并将此输出后处理到最终的 EDI。这将为第一个原始翻译提供可读的文本,在第二个阶段可能会完成。

出于程序员的心,您可以在 XSLT 中定义一些 java 函数,例如将常量转换为 EDI 代码。


在 XSLT 中:

我使用wikipedia 的示例,它产生一条 EDI 记录。

用法

    XmlToEdi xmlToEdi = new XmlToEdi();

    String xml = "<S_NAD>\n" +
        "  <D_3035>BY</D_3035>\n" +
        "  <C_C082><D_3039>CST9955</D_3039><D_3055>91</D_3055></C_C082>\n" +
        "  <C_C080><D_3036>Candy Inc</D_3036></C_C080>\n" +
        "  <C_C059><D_3042>Sirup street 15</D_3042></C_C059>\n" +
        "  <D_3164>Sugar Town</D_3164>\n" +
        "  <D_3251>55555</D_3251>\n" +
        "</S_NAD>";
    String expectedEdi =
            "NAD+BY+CST9955::91++Candy Inc+Sirup street 15+Sugar Town++55555";

    try {
        String edi = xmlToEdi.convert(xml);
        System.out.println(xml);
        System.out.println(edi);
        System.out.println(expectedEdi);
        System.out.println(edi.equals(expectedEdi));
    } catch (TransformerException ex) {
        Logger.getLogger(XmlToEdi.class.getName()).log(Level.SEVERE, null, ex);
    }

XmlToEdi 类:

publicString convert(String xml) throws TransformerConfigurationException,
            TransformerException {
    StringReader xmlFile = new StringReader(xml);
    String xsltFile = getClass().getResource("/workbench2/edi.xsl").toExternalForm();

    Source xmlSource = new StreamSource(xmlFile);
    Source xsltSource = new StreamSource(xsltFile);

    StringWriter edi = new StringWriter();
    Result result = new StreamResult(edi);

    TransformerFactory transFact = TransformerFactory.newInstance();
    Transformer trans = transFact.newTransformer(xsltSource);
    trans.transform(xmlSource, result);
    return edi.toString();
}

XSLT 样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
    <!--xsl:strip-space elements="*"/-->

    <xsl:template match="/S_NAD"><xsl:text>NAD</xsl:text>
        <xsl:text>+</xsl:text><xsl:apply-templates select="./D_3035"/><xsl:if test="not(D_3035)">***</xsl:if>
        <xsl:text>+</xsl:text><xsl:apply-templates select="./C_C082"/>
        <xsl:text>+</xsl:text><xsl:apply-templates select="./C_C080"/>
        <xsl:text>+</xsl:text><xsl:apply-templates select="./C_C059"/>
        <xsl:text>+</xsl:text><xsl:apply-templates select="./D_3164"/><xsl:if test="not(D_3164)">***</xsl:if>
        <xsl:text>+</xsl:text><xsl:apply-templates select="./D_XXXX"/><xsl:if test="not(D_XXXX)"></xsl:if>
        <xsl:text>+</xsl:text><xsl:apply-templates select="./D_3251"/><xsl:if test="not(D_3251)">***</xsl:if>
    </xsl:template>

    <xsl:template match="C_C082">
        <xsl:apply-templates select="D_3039"/>
        <xsl:text>:</xsl:text><xsl:apply-templates select="D_XXXX"/>
        <xsl:text>:</xsl:text><xsl:apply-templates select="D_3055"/>
    </xsl:template>

    <xsl:template match="C_C080">
        <xsl:text>+</xsl:text><xsl:apply-templates select="D_XXXX"/>
        <xsl:apply-templates select="D_3036"/>
    </xsl:template>

    <xsl:template match="C_C059">
        <xsl:value-of select="D_3042"/>
    </xsl:template>

</xsl:stylesheet>

严格使用 xsl:text 而不是立即文本导致 xsl 的空白不输出。

有几种使用 XSL 的方法。这个尝试遵循明确说明要拾取哪些子元素的 EDIFACT 语法。上面我使用了D_XXXX 作为未提供的可选元素。通过测试,甚至可以输出一个 EDI 值,其中缺少 XML (***)。

最后一句话:

XSLT 有时会让人非常沮丧,并且几乎会犹豫是否要告诉别人使用 XSLT。 但是给定的样式表表明它不一定是不可读的(尽管 XML 很冗长),而且作为一种小语言,它包含很多功能。

【讨论】:

  • 乔普,我能得到任何 xml 到 edi 转换的示例吗?我研究过,但没有找到任何示例。
  • 在 SO 中有一个类似的问题,唯一的解决方案是“自己动手”。我不能完全相信,但没关系。会给出一个 XSLT 代码 sn-p。
  • 谢谢 Joop,sn-p 提供的帮助很大。参考这些信息,我可以设计自己的架构。
猜你喜欢
  • 2021-11-06
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多