使用累加器规则记住上下文信息

时间:2019-12-12 15:44:26

标签: xslt saxon xslt-3.0

简短问题:

为什么我的xsl:accumulator-rule  <xsl:when test="substring($msg, $value, string-length(./TagField/@value)) != ./TagField/@value">不适用于Saxon PE 9.9,但适用于XSL Professional 2020 sp1。撒克逊人报告的错误是:

  

错误评估(fn:accumulator-before(...)=   xsl:when / @ test的第45行第100列中的fn:accumulator-after(...))   format.xslt:XPTY0004:不允许使用空序列,因为   fn:substring()的第二个参数。在雾化第一个时发现   带有match =“ pattern匹配的模板规则中的'='操作数   node()/ element(Q {} MessageFormat)/ element(Q {} StructFormat)[(not(attribute :: attribute(Q {} repeat)))   和child :: element(Q {} TagField)]“在format.xslt的第82行        内置模板规则(浅拷贝)调用        由xsl:apply-templates调用在文件:/ D:/issue/pfr-transportevent-v01/config/transformation/xslt/format.xslt#102   在format.xslt的第101行的过程complete-struct中:        由global xsl:variable调用在template规则中,在format.xslt的第104行上具有match =“ /”的值不允许使用空序列作为   fn:substring()的第二个参数。在雾化第一个时发现   '='的操作数

这是我完整的xsl:accumulator

<xsl:accumulator name="position-count" as="xs:integer?" initial-value="1" streamable="no">
       <xsl:accumulator-rule match="$MFL/MessageFormat/StructFormat" phase="end">
           <xsl:choose>
               <xsl:when test="./@repeat = '*' ">
                   <xsl:choose>
                       <xsl:when test="substring($msg, $value, string-length(./TagField/@value)) != ./TagField/@value">
                           <xsl:sequence select="$value"/>
                       </xsl:when>
                       <xsl:otherwise>
                           <xsl:variable name="repeat" select="count(tokenize(fn:substring($msg, $value) , ./TagField/@value)) - 1"/>
                           <xsl:sequence select="$value + map:get($groupsize, ./@name) * $repeat"/>
                       </xsl:otherwise>
                   </xsl:choose>
               </xsl:when>
               <xsl:when test="substring($msg, $value, string-length(./TagField/@value)) = ./TagField/@value">
                   <!--<xsl:sequence select="$value + xs:integer(sum(.//FieldFormat/@length)) + string-length(./TagField/@value)"/>-->
                   <xsl:sequence select="$value + map:get($groupsize, string(./@name))"/>
               </xsl:when>
               <xsl:otherwise>
                   <xsl:value-of select="$value"/>
               </xsl:otherwise>
           </xsl:choose>
       </xsl:accumulator-rule>
   </xsl:accumulator>

背景:

我必须解决以下问题,例如,输入是长度可变的纯文本

"H0 EVU_DBSRD PVG Z24 ABF-RF IR 0112019-12-10-14.46.18.553122NJJNNJNM1 80142455360001 M2 10.12.201914:40:00Z1 RABWR1 10.12.2019 10.12.201914:40:00 0000R1 00133807843874880201912103988789201912101530419325346965 000 NN R1 002338078480716 201912101446013716142455 000 NN R1 00324714370125580201912103961427201912101200186865346965 000 NN R1 00433807840438580201912103984329201912101530381256346965 000 NN R1 00524714273013180201912093997400201912090900494682346965 000 NN R1 00637847829609880201912104006488201912101530572232346965 000 NN R1 00737807836474280201912103954824201912101530128369346965 000 NN R1 008338079134858 201912101446013858142455 000 NN R1 00933807849379280201912103979328201912101530334318346965 000 NN R1 01037847829649480201912103990982201912101530433292346965 000 NN R1 011338078414616 201912101446013616142455 000 NN "

(我将文本放在引号中以在最后一个字符N后面保留空格)

预期结果如下:

<?xml version="1.0" encoding="UTF-8"?>
<TransportEvent>
    <TransportEventHeader>
        <NotificationTriggeringOU>EVU_DBSRD</NotificationTriggeringOU>
        <NotificationTriggeringIT>PVG</NotificationTriggeringIT>
        <NotificationReference>Z</NotificationReference>
        <NotificationCode>24</NotificationCode>
        <NotificationType>ABF-RF</NotificationType>
        <NotificationStatus>I</NotificationStatus>
        <NotificationTripType>R</NotificationTripType>
        <ProducingRailwayUndertaking/>
        <ExternalPartner>                                   </ExternalPartner>
        <ActualNumberOfWagons>11</ActualNumberOfWagons>
        <ProcessingTime>2019-12-10-14.46.18.553122</ProcessingTime>
        <NotificationFunctionalClassification>
            <OrderRelevant>N</OrderRelevant>
            <TimetableRelevant>J</TimetableRelevant>
            <CapacityRelevant>J</CapacityRelevant>
            <IntermodalRelevant>N</IntermodalRelevant>
            <XrailRelevant>N</XrailRelevant>
            <NotificationLocationRelevant>J</NotificationLocationRelevant>
        </NotificationFunctionalClassification>
        <Reserve>N</Reserve>
    </TransportEventHeader>
    <NotificationLocation>
        <CurrentLocation>
            <CurrentLocationRL100/>
            <CurrentLocationLocationType/>
            <CurrentUICRailAuthorityNumber>    80</CurrentUICRailAuthorityNumber>
            <CurrentNetworkLocationNumber>142455</CurrentNetworkLocationNumber>
            <CurrentLocationSatelliteNumber>36</CurrentLocationSatelliteNumber>
            <CurrentFreightCarLocationNumber>0001</CurrentFreightCarLocationNumber>
        </CurrentLocation>
        <NextLocation>
            <NextLocationRL100/>
            <NextLocationLocationType/>
            <NextUICRailAuthorityNumber/>
            <NextNetworkLocationNumber/>
            <NextLocationSatelliteNumber/>
            <NextFreightCarLocationNumber/>
        </NextLocation>
    </NotificationLocation>
    <NotificationTime>
        <ActualTime>10.12.201914:40:00</ActualTime>
    </NotificationTime>
    <Trip>
        <TripNumber>RABWR1</TripNumber>
        <RegionDBNetz/>
        <NationalProductionDate>10.12.2019</NationalProductionDate>
        <TrainTypeMainNumber/>
        <TrainTypeSubNumber/>
        <DepartureStationRL100/>
        <DepartureStationUICRailAuthority/>
        <DepartureStationNetworkLocation/>
        <TargetTime>10.12.201914:40:00</TargetTime>
        <RelativeTime> 0000</RelativeTime>
    </Trip>
    <Ordering>
        <OrderingPosition>1</OrderingPosition>
        <OrderingVehicleNumber>338078438748</OrderingVehicleNumber>
        <OrderingCommercialOrderKey>80201912103988789</OrderingCommercialOrderKey>
        <OrderingProductionOrderKey>201912101530419325346965</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>2</OrderingPosition>
        <OrderingVehicleNumber>338078480716</OrderingVehicleNumber>
        <OrderingCommercialOrderKey/>
        <OrderingProductionOrderKey>201912101446013716142455</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>3</OrderingPosition>
        <OrderingVehicleNumber>247143701255</OrderingVehicleNumber>
        <OrderingCommercialOrderKey>80201912103961427</OrderingCommercialOrderKey>
        <OrderingProductionOrderKey>201912101200186865346965</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>4</OrderingPosition>
        <OrderingVehicleNumber>338078404385</OrderingVehicleNumber>
        <OrderingCommercialOrderKey>80201912103984329</OrderingCommercialOrderKey>
        <OrderingProductionOrderKey>201912101530381256346965</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>5</OrderingPosition>
        <OrderingVehicleNumber>247142730131</OrderingVehicleNumber>
        <OrderingCommercialOrderKey>80201912093997400</OrderingCommercialOrderKey>
        <OrderingProductionOrderKey>201912090900494682346965</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>6</OrderingPosition>
        <OrderingVehicleNumber>378478296098</OrderingVehicleNumber>
        <OrderingCommercialOrderKey>80201912104006488</OrderingCommercialOrderKey>
        <OrderingProductionOrderKey>201912101530572232346965</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>7</OrderingPosition>
        <OrderingVehicleNumber>378078364742</OrderingVehicleNumber>
        <OrderingCommercialOrderKey>80201912103954824</OrderingCommercialOrderKey>
        <OrderingProductionOrderKey>201912101530128369346965</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>8</OrderingPosition>
        <OrderingVehicleNumber>338079134858</OrderingVehicleNumber>
        <OrderingCommercialOrderKey/>
        <OrderingProductionOrderKey>201912101446013858142455</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>9</OrderingPosition>
        <OrderingVehicleNumber>338078493792</OrderingVehicleNumber>
        <OrderingCommercialOrderKey>80201912103979328</OrderingCommercialOrderKey>
        <OrderingProductionOrderKey>201912101530334318346965</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>10</OrderingPosition>
        <OrderingVehicleNumber>378478296494</OrderingVehicleNumber>
        <OrderingCommercialOrderKey>80201912103990982</OrderingCommercialOrderKey>
        <OrderingProductionOrderKey>201912101530433292346965</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
    <Ordering>
        <OrderingPosition>11</OrderingPosition>
        <OrderingVehicleNumber>338078414616</OrderingVehicleNumber>
        <OrderingCommercialOrderKey/>
        <OrderingProductionOrderKey>201912101446013616142455</OrderingProductionOrderKey>
        <OrderingConsignmentNumberID/>
        <OrderingTrainGroup>0</OrderingTrainGroup>
        <FlagActivation/>
        <FlagClosing/>
        <FlagCompletion/>
        <FlagSuspended/>
        <WagonIntermodal>N</WagonIntermodal>
        <OderIntermodal>N</OderIntermodal>
        <Activation>
            <ActivationRL100Location/>
            <ActivationLocationLocationType/>
            <ActivationUICRailAuthorityLocationNumber/>
            <ActivationNetworkLocationNumber/>
            <ActivationSatelliteLocationNumber/>
            <ActivationFreightCarLocationNumber/>
        </Activation>
        <Completion>
            <CompletionRL100Location/>
            <CompletionLocationLocationType/>
            <CompletionUICRailAuthorityLocationNumber/>
            <CompletionNetworkLocationNumber/>
            <CompletionSatelliteLocationNumber/>
            <CompletionFreightCarLocationNumber/>
        </Completion>
    </Ordering>
</TransportEvent>

我的XSLT tempalte使用XML Spy Pro 2020 sp1,但是使用saxon 9.9 PE时,我在累加器规则中遇到累加器错误。

我知道Saxon的实现严格遵守W3C XSLT规范,XML Spy Pro通常并不总是如此。我的``累加器规则''有什么问题?

1 个答案:

答案 0 :(得分:0)

由于我的帖子过长,因此我必须在此处添加更多文本:

在XML文件中指定生成xml的规则:

<?xml version='1.0' encoding='UTF-8'?>
<MessageFormat name='TransportEvent' version='2.02'>
    <StructFormat name='TransportEventHeader' delimOptional='n'>
        <TagField type='String' value='H0 '/>
        <FieldFormat name='NotificationTriggeringOU' type='String' delimOptional='y' length='10' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='NotificationTriggeringIT' type='String' delimOptional='y' length='8' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='NotificationReference' type='String' delimOptional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='NotificationCode' type='String' delimOptional='y' length='3' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='NotificationType' type='String' delimOptional='y' length='8' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='NotificationStatus' type='String' delimOptional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='NotificationTripType' type='String' delimOptional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='ProducingRailwayUndertaking' type='String' delimOptional='y' optional='y' length='4' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='ExternalPartner' type='String' delimOptional='y' optional='y' length='35' />
        <FieldFormat name='ActualNumberOfWagons' type='Numeric' delimOptional='y' optional='y' length='3' pad='0' padType='leading' trimLeading='0'/>
        <FieldFormat name='ProcessingTime' type='String' delimOptional='y' length='26' pad=' ' padType='trailing' trimTrailing=' '/>
        <StructFormat name='NotificationFunctionalClassification' delimOptional='y' optional='y'>
            <FieldFormat name='OrderRelevant' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='TimetableRelevant' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CapacityRelevant' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='IntermodalRelevant' type='String' delimOptional='y' optional='y' length='1' />
            <FieldFormat name='XrailRelevant' type='String' delimOptional='y' optional='y' length='1' />
            <FieldFormat name='NotificationLocationRelevant' type='String' delimOptional='y' optional='y' length='1' />
        </StructFormat>
        <FieldFormat name='Reserve' type='String' delimOptional='y' length='1' />
    </StructFormat>
    <StructFormat name='NotificationLocation' delimOptional='n' optional='y'>
        <TagField type='String' value='M1 '/>
        <StructFormat name='CurrentLocation' delimOptional='y' optional='y'>
            <FieldFormat name='CurrentLocationRL100' type='String' delimOptional='y' optional='y' length='5' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CurrentLocationLocationType' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CurrentUICRailAuthorityNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CurrentNetworkLocationNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CurrentLocationSatelliteNumber' type='String' delimOptional='y' optional='y' length='2' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CurrentFreightCarLocationNumber' type='String' delimOptional='y' optional='y' length='4' pad=' ' padType='trailing' trimTrailing=' '/>
        </StructFormat>
        <StructFormat name='NextLocation' delimOptional='y' optional='y'>
            <FieldFormat name='NextLocationRL100' type='String' delimOptional='y' optional='y' length='5' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='NextLocationLocationType' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='NextUICRailAuthorityNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='NextNetworkLocationNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='NextLocationSatelliteNumber' type='String' delimOptional='y' optional='y' length='2' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='NextFreightCarLocationNumber' type='String' delimOptional='y' optional='y' length='4' pad=' ' padType='trailing' trimTrailing=' '/>
        </StructFormat>
    </StructFormat>
    <StructFormat name='NotificationTime' delimOptional='n'>
        <TagField type='String' value='M2 '/>
        <FieldFormat name='ActualTime' type='String' delimOptional='y' length='18' pad=' ' padType='trailing' trimTrailing=' '/>
    </StructFormat>
    <StructFormat name='Trip' delimOptional='n' optional='y'>
        <TagField type='String' value='Z1 '/>
        <FieldFormat name='TripNumber' type='String' delimOptional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='RegionDBNetz' type='String' delimOptional='y' optional='y' length='2' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='NationalProductionDate' type='String' delimOptional='y' optional='y' length='10' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='TrainTypeMainNumber' type='String' delimOptional='y' optional='y' length='2' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='TrainTypeSubNumber' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='DepartureStationRL100' type='String' delimOptional='y' optional='y' length='5' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='DepartureStationUICRailAuthority' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='DepartureStationNetworkLocation' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='TargetTime' type='String' delimOptional='y' optional='y' length='18' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='RelativeTime' type='String' delimOptional='y' optional='y' length='5' pad='0' padType='leading' trimTrailing=' '/>
    </StructFormat>
    <StructFormat name='HandoverTakeover' delimOptional='n' optional='y'>
        <TagField type='String' value='U1 '/>
        <FieldFormat name='HandoverTakeoverFlag' type='String' delimOptional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='ConsigningRU' type='String' delimOptional='y' length='4' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='AcceptingRU' type='String' delimOptional='y' length='4' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='UICBorderCode' type='String' delimOptional='y' optional='y' length='3' pad=' ' padType='trailing' trimTrailing=' '/>
    </StructFormat>
    <StructFormat name='Ordering' delimOptional='n' optional='y' repeat='*'>
        <TagField type='String' value='R1 '/>
        <FieldFormat name='OrderingPosition' type='Numeric' delimOptional='y' optional='y' length='3' pad='0' padType='leading' trimLeading='0'/>
        <FieldFormat name='OrderingVehicleNumber' type='String' delimOptional='y' optional='y' length='12' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='OrderingCommercialOrderKey' type='String' delimOptional='y' optional='y' length='17' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='OrderingProductionOrderKey' type='String' delimOptional='y' optional='y' length='24' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='OrderingConsignmentNumberID' type='String' delimOptional='y' optional='y' length='35' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='OrderingTrainGroup' type='Numeric' delimOptional='y' optional='y' length='3' pad='0' padType='leading' trimLeading='0'/>
        <FieldFormat name='FlagActivation' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='FlagClosing' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='FlagCompletion' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='FlagSuspended' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='WagonIntermodal' type='String' delimOptional='y' optional='y' length='1' />
        <FieldFormat name='OderIntermodal' type='String' delimOptional='y' optional='y' length='1' />
        <StructFormat name='Activation' delimOptional='y' optional='y'>
            <FieldFormat name='ActivationRL100Location' type='String' delimOptional='y' optional='y' length='5' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='ActivationLocationLocationType' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='ActivationUICRailAuthorityLocationNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='ActivationNetworkLocationNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='ActivationSatelliteLocationNumber' type='String' delimOptional='y' optional='y' length='2' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='ActivationFreightCarLocationNumber' type='String' delimOptional='y' optional='y' length='4' pad=' ' padType='trailing' trimTrailing=' '/>
        </StructFormat>
        <StructFormat name='Completion' delimOptional='y' optional='y'>
            <FieldFormat name='CompletionRL100Location' type='String' delimOptional='y' optional='y' length='5' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CompletionLocationLocationType' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CompletionUICRailAuthorityLocationNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CompletionNetworkLocationNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CompletionSatelliteLocationNumber' type='String' delimOptional='y' optional='y' length='2' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='CompletionFreightCarLocationNumber' type='String' delimOptional='y' optional='y' length='4' pad=' ' padType='trailing' trimTrailing=' '/>
        </StructFormat>
    </StructFormat>
    <StructFormat name='Vehicle' delimOptional='n' optional='y' repeat='*'>
        <TagField type='String' value='F1 '/>
        <FieldFormat name='VehicleNumber' type='String' delimOptional='y' length='12' pad=' ' padType='trailing' trimTrailing=' '/>
        <StructFormat name='Damage' delimOptional='y' optional='y'>
            <FieldFormat name='CapabilityCode' type='String' delimOptional='y' optional='y' length='1' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='HighDemandFromDate' type='String' delimOptional='y' optional='y' length='10' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='LastCarInspectorTime' type='String' delimOptional='y' optional='y' length='18' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='DamageTypeCode' type='String' delimOptional='y' optional='y' length='3' repeat='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='DamageCauseCode' type='String' delimOptional='y' optional='y' length='1' repeat='6' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='DamageDeploymentConstraint' type='String' delimOptional='y' optional='y' length='2' repeat='3' pad=' ' padType='trailing' trimTrailing=' '/>
            <FieldFormat name='DamageMaxSpeed' type='Numeric' delimOptional='y' optional='y' length='3' pad='0' padType='leading' trimLeading='0'/>
        </StructFormat>
    </StructFormat>
    <StructFormat name='Order' delimOptional='n' optional='y' repeat='*'>
        <TagField type='String' value='A1 '/>
        <FieldFormat name='VehicleNumber' type='String' delimOptional='y' length='12' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='CommercialOrderKey' type='String' delimOptional='y' optional='y' length='17' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='ProductionOrderKey' type='String' delimOptional='y' optional='y' length='24' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='ConsignmentNumberID' type='String' delimOptional='y' optional='y' length='35' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='OrderEntrySystem' type='String' delimOptional='y' optional='y' length='3' pad='  ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='TransportType' type='String' delimOptional='y' optional='y' length='2' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='DispatchDate' type='String' delimOptional='y' optional='y' length='10' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='DispatchNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='DestinationDispatchUICRailAuthorityNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='DestinationDispatchLocationNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='DestinationReceptionUICRailAuthorityNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='DestinationReceptionLocationNumber' type='String' delimOptional='y' optional='y' length='6' pad=' ' padType='trailing' trimTrailing=' '/>
        <FieldFormat name='FreightNetLoad' type='Numeric' delimOptional='y' optional='y' length='6' pad='0' padType='leading' trimLeading='0'/>
    </StructFormat>
</MessageFormat>

这是我的XSLT模板。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:csb="http://www.dbcargo.org/csb" xmlns:map="http://www.w3.org/2005/xpath-functions/map" exclude-result-prefixes="#all" version="3.0">
    <xsl:param name="msg" as="xs:string">H0 EVU_DBSRD PVG     Z24 ABF-RF  IR                                       0112019-12-10-14.46.18.553122NJJNNJNM1           80142455360001                        M2 10.12.201914:40:00Z1 RABWR1  10.12.2019                    10.12.201914:40:00 0000R1 00133807843874880201912103988789201912101530419325346965                                   000    NN                                                R1 002338078480716                 201912101446013716142455                                   000    NN                                                R1 00324714370125580201912103961427201912101200186865346965                                   000    NN                                                R1 00433807840438580201912103984329201912101530381256346965                                   000    NN                                                R1 00524714273013180201912093997400201912090900494682346965                                   000    NN                                                R1 00637847829609880201912104006488201912101530572232346965                                   000    NN                                                R1 00737807836474280201912103954824201912101530128369346965                                   000    NN                                                R1 008338079134858                 201912101446013858142455                                   000    NN                                                R1 00933807849379280201912103979328201912101530334318346965                                   000    NN                                                R1 01037847829649480201912103990982201912101530433292346965                                   000    NN                                                R1 011338078414616                 201912101446013616142455                                   000    NN                                                </xsl:param>
    <xsl:param name="relatviePath2MFL" as="xs:string" select="'./rules.xml'"/>
    <xsl:variable name="MFL" select="document($relatviePath2MFL)"/>
    <xsl:output method="xml" indent="yes"/>
    <xsl:mode name="unroll" on-no-match="shallow-copy" use-accumulators="position-count"/>
    <xsl:strip-space elements="*"/>
    <xsl:variable name="minimalBeginOfRepeatGroup" as="xs:integer" select="fn:string-length($msg) - sum(/MessageFormat/StructFormat[not(@optional='y')]//FieldFormat/@length) + string-length( string-join(/MessageFormat/StructFormat[not(@optional='y')]//TagField/@value))"/>
    <xsl:variable name="groupsize" as="map(xs:string, xs:integer)">
        <xsl:map>
            <xsl:for-each select="/MessageFormat/StructFormat">
                <xsl:choose>
                    <!-- there are FieldFormat with repeat attribute -->
                    <xsl:when test=".//FieldFormat[@repeat]">
                        <xsl:variable name="sum1" select="xs:integer( sum(.//FieldFormat[not(@repeat)]/@length))"/>
                        <xsl:variable name="sum2" select="xs:integer( sum(for-each(.//FieldFormat[@repeat], function ($arg) as xs:integer {xs:integer($arg/@length) * xs:integer($arg/@repeat)})))"/>
                        <xsl:map-entry key="string(./@name)">
                            <xsl:sequence select="xs:integer( $sum1 + $sum2 + string-length(./TagField/@value))"/>
                        </xsl:map-entry>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:map-entry key="string(./@name)">
                            <xsl:sequence select="xs:integer( sum(.//FieldFormat/@length)) + string-length(./TagField/@value)"/>
                        </xsl:map-entry>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>
        </xsl:map>
    </xsl:variable>
    <xsl:accumulator name="position-count" as="xs:integer?" initial-value="1" streamable="no">
        <xsl:accumulator-rule match="$MFL/MessageFormat/StructFormat" phase="end">
            <xsl:choose>
                <xsl:when test="./@repeat = '*' ">
                    <xsl:choose>
                        <xsl:when test="substring($msg, $value, string-length(./TagField/@value)) != ./TagField/@value">
                            <xsl:sequence select="$value"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:variable name="repeat" select="count(tokenize(fn:substring($msg, $value) , ./TagField/@value)) - 1"/>
                            <xsl:sequence select="$value + map:get($groupsize, ./@name) * $repeat"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:when>
                <xsl:when test="substring($msg, $value, string-length(./TagField/@value)) = ./TagField/@value">
                    <xsl:sequence select="$value + map:get($groupsize, string(./@name))"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$value"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:accumulator-rule>
    </xsl:accumulator>
    <xsl:template match="StructFormat[@repeat]" mode="unroll">
        <xsl:variable name="this" select="."/>
        <xsl:choose>
            <xsl:when test="$this/@repeat != '*' ">
                <xsl:for-each select="1 to @repeat">
                    <xsl:choose>
                        <xsl:when test="$this/@delimOptional = 'n' and $this/TagField and contains($msg, $this/TagField)">
                            <xsl:copy select="$this">
                                <xsl:apply-templates select="@* except @repeat, node()" mode="#current"/>
                            </xsl:copy>
                        </xsl:when>
                        <xsl:otherwise/>
                    </xsl:choose>
                </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="groupMsg" select="fn:substring($msg, fn:accumulator-before('position-count'), fn:accumulator-after('position-count'))"/>
                <xsl:variable name="repeat" select="count(tokenize($groupMsg, $this/TagField/@value)) - 1"/>
                <xsl:comment select="$repeat"/>
                <xsl:for-each select="1 to $repeat">
                    <xsl:copy select="$this">
                        <xsl:apply-templates select="@* except @repeat, node()" mode="#current"/>
                    </xsl:copy>
                </xsl:for-each>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="$MFL/MessageFormat/StructFormat[not(@repeat) and TagField]" mode="unroll">
        <xsl:variable name="this" select="."/>
        <xsl:choose>
            <xsl:when test="fn:accumulator-before('position-count') = fn:accumulator-after('position-count')"/>
            <xsl:otherwise>
                <xsl:copy select="$this">
                    <xsl:apply-templates select="@* except @repeat, node()" mode="#current"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="FieldFormat[@repeat]" mode="unroll">
        <xsl:variable name="this" select="."/>
        <xsl:for-each select="1 to @repeat">
            <xsl:copy select="$this">
                <xsl:apply-templates select="@* except @repeat, node()" mode="#current"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:template>
    <xsl:variable name="complete-struct">
        <xsl:apply-templates select="$MFL/*" mode="unroll"/>
    </xsl:variable>
    <xsl:template match="/">
        <xsl:variable name="group">
            <output>
                <xsl:for-each select="$MFL/MessageFormat/StructFormat">
                    <xsl:if test="fn:accumulator-before('position-count') != fn:accumulator-after('position-count')">
                        <xsl:element name="{./@name}">
                            <xsl:attribute name="start" select="fn:accumulator-before('position-count')"/>
                            <xsl:attribute name="length" select="fn:accumulator-after('position-count')-1"/>
                        </xsl:element>
                    </xsl:if>
                </xsl:for-each>
            </output>
        </xsl:variable>
        <xsl:element name="{$MFL/MessageFormat/@name}">
            <xsl:apply-templates select="$complete-struct/*"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="StructFormat">
        <xsl:element name="{@name}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="FieldFormat">
        <xsl:variable name="precedingFieldFormatsLength" select="sum(preceding::FieldFormat/@length)"/>
        <xsl:variable name="offset">
            <xsl:value-of select="string-length(string-join(./preceding::TagField/@value, ''))"/>
        </xsl:variable>
        <xsl:element name="{@name}">
            <xsl:variable name="value" select="substring($msg, 1 + $precedingFieldFormatsLength + $offset, @length)"/>
            <xsl:value-of select="csb:formatField(.,$value)"/>
        </xsl:element>
    </xsl:template>
    <!-- format output -->
    <xsl:function name="csb:formatField" as="xs:string">
        <xsl:param name="field" as="element()"/>
        <xsl:param name="value" as="xs:string"/>
        <xsl:choose>
            <xsl:when test="$field/@length = '1' and $value = ' '">
                <xsl:value-of select="''"/>
            </xsl:when>
            <!-- remove leading and trailing space -->
            <xsl:when test="$field/@trimLeading = ' ' and $field/@trimTrailing = ' '">
                <xsl:value-of select="fn:replace($value, '^\s+|\s+$', '')"/>
            </xsl:when>
            <!-- remove ONLY leading space -->
            <xsl:when test="$field/@trimLeading = ' '  and fn:not(fn:exists($field//@trimTrailing))">
                <xsl:value-of select="fn:replace($value, '^\s+', '')"/>
            </xsl:when>
            <!-- remove ONLY trailing space -->
            <xsl:when test="$field/@trimTrailing = ' '  and fn:not(fn:exists($field//@trimLeading))">
                <xsl:value-of select="fn:replace($value, '\s+$', '')"/>
            </xsl:when>
            <!-- remove leading 0 -->
            <xsl:when test="$field/@type = 'Numeric'  and $field/@trimLeading = '0'  and fn:not(fn:exists($field//@trimTrailing))">
                <!-- <xsl:value-of select="fn:replace($value, '^0+', '')"/> -->
                <xsl:if test="number($value) != number($value)">
                    <!-- validate data -->
                    <xsl:message terminate="yes">
                        <xsl:value-of select="concat('Transformation failed. The field', $field, ' has invalid value')"/>
                    </xsl:message>
                </xsl:if>
                <xsl:value-of select="number($value)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$value"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>
</xsl:stylesheet>