首页 > 解决方案 > 使用 xs:assert XSD 1.1 比较来自不同父级的两个 xml 元素

问题描述

我可以使用 xs:assert 比较来自不同父母的两个 xml 元素吗,例如我想比较 <xs:assert test="pa:MsgId eq pa:EndToEndId"/> 或者可能正在检查 NbOfTxs = 出现 CdtTrfTxInf 的时间元素的数量。

目前我收到错误,即架构类型“GroupHeader32”上元素“GrpHdr”的断言评估(“pa:NbOfTxs=pa:EndToEndId”)没有成功。

如果需要,很高兴提供更多详细信息:

<xs:schema attributeFormDefault="unqualified" xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    targetNamespace="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"
    xmlns:xerces="http://xerces.apache.org">    <xs:element name="Document" type="Document"/>

    <xs:complexType name="Document">
        <xs:sequence>
            <xs:element name="CstmrCdtTrfInitn" type="CustomerCreditTransferInitiationV03"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="CustomerCreditTransferInitiationV03">
        <xs:sequence>
            <xs:element name="GrpHdr" type="GroupHeader32"/>
            <xs:element maxOccurs="unbounded" minOccurs="1" name="PmtInf" type="PaymentInstructionInformation3"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="GroupHeader32">       
        <xs:sequence>
            <xs:element name="MsgId" type="Max35Text"/>
            <xs:element name="CreDtTm" type="ISODateTime"/>
            <xs:element maxOccurs="2" minOccurs="0" name="Authstn" type="Authorisation1Choice"/>
            <xs:element name="NbOfTxs" type="Max15NumericText"/>
            <xs:element maxOccurs="1" minOccurs="0" name="CtrlSum" type="DecimalNumber"/>
            <xs:element name="InitgPty" type="PartyIdentification32"/>
            <xs:element maxOccurs="1" minOccurs="0" name="FwdgAgt" type="BranchAndFinancialInstitutionIdentification4"/>
        </xs:sequence>
        <xs:assert test="pa:MsgId eq pa:EndToEndId"/>
    </xs:complexType>

   <xs:complexType name="CustomerCreditTransferInitiationV03">
        <xs:sequence>
            <xs:element name="GrpHdr" type="GroupHeader32"/>
            <xs:element maxOccurs="unbounded" minOccurs="1" name="PmtInf" type="PaymentInstructionInformation3"/>
        </xs:sequence>
    </xs:complexType>

        <xs:complexType name="Document">
            <xs:sequence>
                <xs:element name="CstmrCdtTrfInitn" type="CustomerCreditTransferInitiationV03"/>
            </xs:sequence>
        </xs:complexType>

    <xs:complexType name="PaymentIdentification1">
        <xs:sequence>
            <xs:element maxOccurs="1" minOccurs="0" name="InstrId" type="Max35Text"/>
            <xs:element name="EndToEndId" type="Max35Text"/>
        </xs:sequence>
    </xs:complexType>

 <xs:complexType name="PaymentInstructionInformation3">
        <xs:sequence>
            <xs:element name="PmtInfId" type="Max35Text"/>
            <xs:element name="PmtMtd" type="PaymentMethod3Code"/>
            <xs:element maxOccurs="1" minOccurs="0" name="BtchBookg" type="BatchBookingIndicator"/>
            <xs:element maxOccurs="1" minOccurs="0" name="NbOfTxs" type="Max15NumericText"/>
            <xs:element maxOccurs="1" minOccurs="0" name="CtrlSum" type="DecimalNumber"/>
            <xs:element maxOccurs="1" minOccurs="0" name="PmtTpInf" type="PaymentTypeInformation19"/>
            <xs:element name="ReqdExctnDt" type="ISODate"/>
            <xs:element maxOccurs="1" minOccurs="0" name="PoolgAdjstmntDt" type="ISODate"/>
            <xs:element name="Dbtr" type="PartyIdentification32"/>
            <xs:element name="DbtrAcct" type="CashAccount16"/>
            <xs:element name="DbtrAgt" type="BranchAndFinancialInstitutionIdentification4"/>
            <xs:element maxOccurs="1" minOccurs="0" name="DbtrAgtAcct" type="CashAccount16"/>
            <xs:element maxOccurs="1" minOccurs="0" name="UltmtDbtr" type="PartyIdentification32"/>
            <xs:element maxOccurs="1" minOccurs="0" name="ChrgBr" type="ChargeBearerType1Code"/>
            <xs:element maxOccurs="1" minOccurs="0" name="ChrgsAcct" type="CashAccount16"/>
            <xs:element maxOccurs="1" minOccurs="0" name="ChrgsAcctAgt" type="BranchAndFinancialInstitutionIdentification4"/>
            <xs:element maxOccurs="unbounded" minOccurs="1" name="CdtTrfTxInf" type="CreditTransferTransactionInformation10"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

    <xs:complexType name="CreditTransferTransactionInformation10">
        <xs:sequence>
            <xs:element name="PmtId" type="PaymentIdentification1"/>
            <xs:element maxOccurs="1" minOccurs="0" name="PmtTpInf" type="PaymentTypeInformation19"/>
            <xs:element name="Amt" type="AmountType3Choice"/>
            <xs:element maxOccurs="1" minOccurs="0" name="XchgRateInf" type="ExchangeRateInformation1"/>
            <xs:element maxOccurs="1" minOccurs="0" name="ChrgBr" type="ChargeBearerType1Code"/>
            <xs:element maxOccurs="1" minOccurs="0" name="ChqInstr" type="Cheque6"/>
            <xs:element maxOccurs="1" minOccurs="0" name="UltmtDbtr" type="PartyIdentification32"/>
            <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt1" type="BranchAndFinancialInstitutionIdentification4"/>
            <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt1Acct" type="CashAccount16"/>
            <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt2" type="BranchAndFinancialInstitutionIdentification4"/>
            <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt2Acct" type="CashAccount16"/>
            <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt3" type="BranchAndFinancialInstitutionIdentification4"/>
            <xs:element maxOccurs="1" minOccurs="0" name="IntrmyAgt3Acct" type="CashAccount16"/>
            <xs:element maxOccurs="1" minOccurs="0" name="CdtrAgt" type="BranchAndFinancialInstitutionIdentification4"/>
            <xs:element maxOccurs="1" minOccurs="0" name="CdtrAgtAcct" type="CashAccount16"/>
            <xs:element maxOccurs="1" minOccurs="0" name="Cdtr" type="PartyIdentification32"/>
            <xs:element maxOccurs="1" minOccurs="0" name="CdtrAcct" type="CashAccount16"/>
            <xs:element maxOccurs="1" minOccurs="0" name="UltmtCdtr" type="PartyIdentification32"/>
            <xs:element maxOccurs="unbounded" minOccurs="0" name="InstrForCdtrAgt" type="InstructionForCreditorAgent1"/>
            <xs:element maxOccurs="1" minOccurs="0" name="InstrForDbtrAgt" type="Max140Text"/>
            <xs:element maxOccurs="1" minOccurs="0" name="Purp" type="Purpose2Choice"/>
            <xs:element maxOccurs="10" minOccurs="0" name="RgltryRptg" type="RegulatoryReporting3"/>
            <xs:element maxOccurs="1" minOccurs="0" name="Tax" type="TaxInformation3"/>
            <xs:element maxOccurs="10" minOccurs="0" name="RltdRmtInf" type="RemittanceLocation2"/>
            <xs:element maxOccurs="1" minOccurs="0" name="RmtInf" type="RemittanceInformation5"/>
        </xs:sequence>
    </xs:complexType>

我的示例 XML 如下所示:我正在尝试将 MsgId 与 endtoendid 进行比较,并且还想检查 NbOfTxs 字段值是否应该等于出现的次数

<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">
    <CstmrCdtTrfInitn>
        <GrpHdr>
            <MsgId>1</MsgId>
            <NbOfTxs>2</NbOfTxs>
        </GrpHdr>
        <PmtInf> 
            <PmtInfId>ABC</PmtInfId>
            <CdtTrfTxInf>
                <PmtId>
                    <EndToEndId>1</EndToEndId>
                </PmtId>
            </CdtTrfTxInf>
            <CdtTrfTxInf>
                <PmtId>
                    <EndToEndId>2</EndToEndId>
                </PmtId>
            </CdtTrfTxInf>
        </PmtInf>
    </CstmrCdtTrfInitn>
</Document>

标签: xmlxsdxsd-validationxml-validationxsd-1.1

解决方案


断言必须放在所有测试的 XML 组件共有的祖先;断言不能引用不是断言出现的元素的后代的组件。

在您的情况下,断言GrpHdr不能引用EndToEndId,因为EndToEndId它不是GrpHldr. 相反,断言必须出现在(或更高)上,这是和CstmrCdtTrfInitn的共同祖先。GrpHdrEndToEndId

如果可以存在多个组件,还要注意确定您的断言是否适用于一个或所有组件。


推荐阅读