SAP JCo 将 XML 解析为带有字段扩展的 IDOC

SAP JCo parse XML to IDOC with field extensions

我在使用 SAP JCo 库将 XML 解析为 IDOC 时遇到了一些问题。我知道我需要连接到给定的 SAP 系统。

这是我的 gradle 测试代码:

    when:
    JCoIDocServer server = JCoIDoc.getServer(sapProperties.get("jco.server.progid"))

    IDocXMLProcessor xmlProcessor = JCoIDoc.getIDocFactory().getIDocXMLProcessor()
    IDocDocumentList iDocDocumentList = xmlProcessor.parse(server.getIDocRepository(), getClass().getResourceAsStream("/data/DEBMAS-406868135.XML"), IDocXMLProcessor.PARSE_IGNORE_UNKNOWN_FIELDS)

连接有效,但 JCo 发现我的 XML 不一致(从 SAP 导出,没有手动更改!)这似乎是由 SAP 扩展字段引起的:

com.sap.conn.idoc.IDocParseException: (7) IDOC_ERROR_PARSE_FAILURE: IDoc type extension ZDEBMAS3 within the EDI_DC40 control record segment does not match the IDoc-XML root tag <DEBMAS05>:

state=READING_ENDTAG, charPosition=852, lineNumber=24, columnNumber=19

如您所见,我尝试使用 XML 解析器选项,但没有帮助。

IDocParser 接受扩展字段时我需要做什么?

更新 1 在这里你可以找到匿名的 IDOC XML.

<?xml version="1.0"?>
<DEBMAS05>
    <IDOC BEGIN="1">
        <EDI_DC40 SEGMENT="1">
            <TABNAM><![CDATA[EDI_DC40]]></TABNAM>
            <MANDT>100</MANDT>
            <DOCNUM>0000000406868135</DOCNUM>
            <DOCREL>750</DOCREL>
            <STATUS>12</STATUS>
            <DIRECT>1</DIRECT>
            <OUTMOD>2</OUTMOD>
            <IDOCTYP>DEBMAS05</IDOCTYP>
            <CIMTYP>ZDEBMAS3</CIMTYP>
            <MESTYP><![CDATA[Z_DEBMAS2]]></MESTYP>
            <SNDPOR>XXX</SNDPOR>
            <SNDPRT>LS</SNDPRT>
            <SNDPRN><![CDATA[P02_100]]></SNDPRN>
            <RCVPOR>INTERNET</RCVPOR>
            <RCVPRT>LS</RCVPRT>
            <RCVPRN>INTERNET</RCVPRN>
            <CREDAT>20190503</CREDAT>
            <CRETIM>085059</CRETIM>
            <SERIAL>20190503081911</SERIAL>
        </EDI_DC40>
        <E1KNA1M SEGMENT="1">
            <MSGFN>004</MSGFN>
            <KUNNR>XXX</KUNNR>
            <ANRED>XXX</ANRED>
            <BBBNR>0000000</BBBNR>
            <BBSNR>00000</BBSNR>
            <BUBKZ>0</BUBKZ>
            <KTOKD>XXX</KTOKD>
            <LAND1>XX</LAND1>
            <NAME1>XXX</NAME1>
            <ORT01>XXX</ORT01>
            <ORT02>XXX</ORT02>
            <PSTLZ>XXX</PSTLZ>
            <REGIO>XXX</REGIO>
            <SORTL>XXX</SORTL>
            <SPRAS>XXX</SPRAS>
            <STRAS>XXX</STRAS>
            <LZONE>0000000001</LZONE>
            <UMJAH>0000</UMJAH>
            <JMZAH>000000</JMZAH>
            <JMJAH>0000</JMJAH>
            <KATR3>XXX</KATR3>
            <KATR7>XXX</KATR7>
            <KATR8>XXX</KATR8>
            <STKZN>X</STKZN>
            <UMSA1>0</UMSA1>
            <HZUOR>00</HZUOR>
            <CIVVE>X</CIVVE>
            <SPRAS_ISO>DE</SPRAS_ISO>
            <ZE1BPAD SEGMENT="1">
                <PARNR>XXX</PARNR>
                <TITLE_P>XXX</TITLE_P>
                <FIRSTNAME>XXX</FIRSTNAME>
                <LASTNAME>XXX</LASTNAME>
                <SORT1_P>XXX</SORT1_P>
                <NAMCOUNTRY>DE</NAMCOUNTRY>
                <NAMCTRYISO>DE</NAMCTRYISO>
                <LANGU_P>D</LANGU_P>
                <LANGUP_ISO>DE</LANGUP_ISO>
            <C_O_NAME>XXX</C_O_NAME>
            <DISTRICT>XXX</DISTRICT>
            <CITY>XXX</CITY>
            <POSTL_COD1>XXX</POSTL_COD1>
            <REGION>XXX</REGION>
            <TRANSPZONE>0000000001</TRANSPZONE>
            <STREET>XXX.</STREET>
            <HOUSE_NO>XXX</HOUSE_NO>
            <PERS_GROUP>XXX</PERS_GROUP>
            <ADDR_GROUP>XXX</ADDR_GROUP>
            <E_MAIL>XXX</E_MAIL>
        </ZE1BPAD>
        <E1KNA11 SEGMENT="1">
            <KNURL>/</KNURL>
            <J_1KFREPRE>/</J_1KFREPRE>
            <J_1KFTBUS>/</J_1KFTBUS>
            <J_1KFTIND>/</J_1KFTIND>
            <PSOIS>/</PSOIS>
            <PSON1>/</PSON1>
            <PSON2>/</PSON2>
            <PSON3>/</PSON3>
            <PSOVN>/</PSOVN>
            <PSOTL>/</PSOTL>
            <PSOO1>/</PSOO1>
            <PSOO2>/</PSOO2>
            <PSOO3>/</PSOO3>
            <PSOO4>/</PSOO4>
            <PSOO5>/</PSOO5>
            <STCD5>/</STCD5>
            <SUFRAMA>/</SUFRAMA>
            <RG>/</RG>
            <EXP>/</EXP>
            <UF>/</UF>
            <RGDATE>/</RGDATE>
            <RIC>/</RIC>
            <RNE>/</RNE>
            <RNEDATE>/</RNEDATE>
            <CNAE>/</CNAE>
            <LEGALNAT>/</LEGALNAT>
            <CRTN>/</CRTN>
            <ICMSTAXPAY>/</ICMSTAXPAY>
            <INDTYP>/</INDTYP>
            <TDT>/</TDT>
            <COMSIZE>/</COMSIZE>
            <DECREGPC>/</DECREGPC>
            <CVP_XBLCK>/</CVP_XBLCK>
        </E1KNA11>
        <E1KNVVM SEGMENT="1">
            <MSGFN>XXX</MSGFN>
            <VKORG>XXX</VKORG>
            <VTWEG>XXX</VTWEG>
            <SPART>XXX</SPART>
            <VERSG>1</VERSG>
            <KALKS>XXX</KALKS>
            <KONDA>XXX</KONDA>
            <AWAHR>XXX</AWAHR>
            <INCO1>FH</INCO1>
            <INCO2>XXX</INCO2>
            <ANTLF>XXX</ANTLF>
            <KZTLF>XXX</KZTLF>
            <LPRIO>XXX</LPRIO>
            <WAERS>XXX</WAERS>
            <KTGRD>XXX</KTGRD>
            <ZTERM>XXX</ZTERM>
            <VWERK>XXX</VWERK>
            <KVGR4>XXX</KVGR4>
            <KVGR5>XXX</KVGR5>
            <UEBTO>XXX</UEBTO>
            <UNTTO>XXX</UNTTO>
            <PVKSM>XXX</PVKSM>
            <PODTG>XXX</PODTG>
            <BLIND>/</BLIND>
            <CARRIER_NOTIF>/</CARRIER_NOTIF>
            <CVP_XBLCK_V>/</CVP_XBLCK_V>
            <INCOV>/</INCOV>
            <INCO2_L>/</INCO2_L>
            <INCO3_L>/</INCO3_L>
            <ZE1KNVV SEGMENT="1">
                <HASH_CODE>XXX</HASH_CODE>
            </ZE1KNVV>
            <E1KNVPM SEGMENT="1">
                <MSGFN>XXX</MSGFN>
                <PARVW>XXX</PARVW>
                <KUNN2>XXX</KUNN2>
                <PARZA>XXX</PARZA>
            </E1KNVPM>
            <E1KNVPM SEGMENT="1">
                <MSGFN>XXX</MSGFN>
                <PARVW>XXX</PARVW>
                <KUNN2>XXX</KUNN2>
                <PARZA>XXX</PARZA>
            </E1KNVPM>
            <E1KNVPM SEGMENT="1">
                <MSGFN>XXX</MSGFN>
                <PARVW>WE</PARVW>
                <KUNN2>XXX</KUNN2>
                <PARZA>XXX</PARZA>
            </E1KNVPM>
        </E1KNVVM>
        <E1KNB1M SEGMENT="1">
            <MSGFN>XXX</MSGFN>
            <BUKRS>XXX</BUKRS>
            <ZUAWA>XXX</ZUAWA>
            <AKONT>XXX</AKONT>
            <ZWELS>XXX</ZWELS>
            <ZTERM>XXX</ZTERM>
            <VZSKZ>XXX</VZSKZ>
            <ZINDT>XXX</ZINDT>
            <ZINRT>XXX</ZINRT>
            <FDGRV>XXX</FDGRV>
            <VLIBB>XXX</VLIBB>
            <VRSZL>XXX</VRSZL>
            <VRSPR>XXX</VRSPR>
            <VERDT>XXX</VERDT>
            <WEBTR>XXX</WEBTR>
            <DATLZ>XXX</DATLZ>
            <XZVER>XXX</XZVER>
            <KULTG>XXX</KULTG>
            <PERNR>XXX</PERNR>
            <GMVKZD>/</GMVKZD>
            <AVSND>/</AVSND>
            <SMTP_ADDR>/</SMTP_ADDR>
            <CVP_XBLCK_B>/</CVP_XBLCK_B>
            <E1KNB5M SEGMENT="1">
                <MSGFN>XXX</MSGFN>
                <MAHNA>XXX</MAHNA>
                <MADAT>XXX</MADAT>
                <MAHNS>XXX</MAHNS>
                <GMVDT>XXX</GMVDT>
            </E1KNB5M>
            <E1KNB5M SEGMENT="1">
                <MSGFN>XXX</MSGFN>
                <MABER>XXX</MABER>
                <MAHNA>XXX</MAHNA>
                <MADAT>XXX</MADAT>
                <MAHNS>XXX</MAHNS>
                <GMVDT>XXX</GMVDT>
            </E1KNB5M>
        </E1KNB1M>
        <E1KNKKM SEGMENT="1">
            <MSGFN>XXX</MSGFN>
            <KKBER>XXX</KKBER>
            <KLIMK>XXX</KLIMK>
            <KNKLI>XXX</KNKLI>
            <CTLPC>XXX</CTLPC>
            <DTREV>XXX</DTREV>
            <SBGRP>XXX</SBGRP>
            <NXTRV>XXX</NXTRV>
            <PAYDB>XXX</PAYDB>
            <REVDB>XXX</REVDB>
            <SBDAT>XXX</SBDAT>
            <DBEKR>XXX</DBEKR>
            <DBMON>XXX</DBMON>
        </E1KNKKM>
    </E1KNA1M>
    <EDI_DS40 SEGMENT="1">
        <MANDT>XXX</MANDT>
        <DOCNUM>XXX</DOCNUM>
        <LOGDAT>XXX</LOGDAT>
        <LOGTIM>XXX</LOGTIM>
        <STATUS>XXX</STATUS>
        <STAMNO>XXX</STAMNO>
        <UNAME><![CDATA[BTCSD_01]]></UNAME>
        <SEGNUM>XXX</SEGNUM>
    </EDI_DS40>
    <EDI_DS40 SEGMENT="1">
        <MANDT>XXX</MANDT>
        <DOCNUM>XXX</DOCNUM>
        <LOGDAT>XXX</LOGDAT>
        <LOGTIM>XXX</LOGTIM>
        <STATUS>XXX</STATUS>
        <STAMQU>XXX</STAMQU>
        <STAMID>XXX</STAMID>
        <STAMNO>XXX</STAMNO>
        <STATYP>XXX</STATYP>
        <STAPA1>XXX</STAPA1>
        <STAPA2>XXX</STAPA2>
        <STAPA3>XXX</STAPA3>
        <STAPA4>XXX</STAPA4>
        <STATXT><![CDATA[&, &, &, &.]]></STATXT>
        <UNAME><![CDATA[BTCSD_01]]></UNAME>
        <SEGNUM>XXX</SEGNUM>
    </EDI_DS40>
    <EDI_DS40 SEGMENT="1">
        <MANDT>XXX</MANDT>
        <DOCNUM>XXX</DOCNUM>
        <LOGDAT>XXX</LOGDAT>
        <LOGTIM>XXX</LOGTIM>
        <STATUS>XXX</STATUS>
        <STAMQU>XXX</STAMQU>
        <STAMID>XXX</STAMID>
        <STAMNO>XXX</STAMNO>
        <STAPA1><![CDATA[SAP_ALE_Z_DEBMAS2]]></STAPA1>
        <STAPA2>XXX</STAPA2>
        <STATXT>XXX</STATXT>
        <UNAME><![CDATA[BTCSD_01]]></UNAME>
        <REPID>XXX</REPID>
        <SEGNUM>XXX</SEGNUM>
    </EDI_DS40>
    <EDI_DS40 SEGMENT="1">
        <MANDT>XXX</MANDT>
        <DOCNUM>XXX</DOCNUM>
        <LOGDAT>XXX</LOGDAT>
        <LOGTIM>XXX</LOGTIM>
        <STATUS>XXX</STATUS>
        <STAMNO>XXX</STAMNO>
        <UNAME><![CDATA[BTCSD_01]]></UNAME>
        <REPID>RBDMOIND</REPID>
        <SEGNUM>XXX</SEGNUM>
    </EDI_DS40>
</IDOC>

更新 2

为了测试,我尝试使用以下代码手动创建一个 IDOC

    JCoIDocServer server = JCoIDoc.getServer(sapProperties.get("jco.server.progid"))
    IDocDocument idoc = JCoIDoc.getIDocFactory().createIDocDocument(server.getIDocRepository(), "DEBMAS05")
    idoc.setValue("MANDT", 100)
    idoc.setValue("IDOCTYP", "DEBMAS05")
    idoc.setValue("CIMTYP", "ZDEBMAS3")
    idoc.setIDocNumber("0000000406868135")


    JCoIDocSegment segment = idoc.rootSegment.addChild("E1KNA1M")

    segment.addChild("ZE1BPAD")

这会导致与使用 xmlProcessor 相同的错误。

但是如果我更改此位置并添加 IDOC 扩展类型

IDocDocument idoc = JCoIDoc.getIDocFactory().createIDocDocument(server.getIDocRepository(), "DEBMAS05","ZDEBMAS3")

错误消失。

更新 3

我好像混淆了两个问题。第一个发生在 JCo 解析 XML 导致此处描述的异常时。

在 JCo 3.0.17 中,引起实现的是 DefaultIDocXMLParser 的第 1321 行

   if (cimType.length() > 0 && !cimType.equals(this.openTags.getFirst()) || cimType.length() == 0 && !iDocType.equals(this.openTags.getFirst())) {
                            throw new IDocParseException("IDoc type " + (cimType.length() > 0 ? "extension " + cimType : iDocType) + " within the EDI_DC40 control record segment does not match the IDoc-XML root tag <" + (String)this.openTags.getFirst() + ">", this.state.name(), this.charPosition, this.lineNumber, this.columnNumber, (String)null, 0);
                        }

要避免此异常,可以删除导致与以编程方式创建的没有扩展类型的 IDOC 相同的异常的元素。

现在的问题是:XML解析器如何配置为接受扩展?

您需要传递有效的 reader 或输入流。 XML 文件不是 class 的资源。 那么请你试试

new FileInputStream(new File("/data/DEBMAS-406868135.XML"))

代替?

添加 IDoc-XML 内容后,我会说解析器的错误消息确实正确。 IDoc-XML 文件内容违反了 SAP 的 IDoc-XML 规范。 在这种情况下,根标记必须是 而不是

根标签必须描述最详细的 IDoc 类型值,这意味着只要没有更多可用的定义 CIMTYP,它就必须包含 IDOCTYP 字段值。但是一旦有一个额外的 CIMTYP,根标签就必须改为包含 CIMTYP 字段值。这是一个奇怪的规则,但这是规则。

所以不是 IDoc-XML 解析器错了,而是生成 IDoc-XML 文件的解析器错了。 恐怕这个 IDoc-XML 解析器没有选项来接受这个错误的 IDoc-XML 数据。您需要更正生成此 IDoc-XML 文件的软件。