У меня есть структура ввода, как показано ниже,
<?xml version="1.0" encoding="UTF-8"?>
<MessageFormat name='WagonStatus_Fplv' version='2.02'>
<StructFormat name='K0-HEADER' delimOptional='n'>
<FieldFormat name='SATZKOPF-K0' type='String' delimOptional='y' length='2' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='Externer_Partner' type='String' delimOptional='y' length='35' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='INTERCHANGEREFERENZNUMMER' type='String' delimOptional='y' length='14' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='NACHRICHTENREFERENZNUMMER' type='String' delimOptional='y' length='14' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='NACHRICHTENTYP' type='String' delimOptional='y' length='6' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='TESTKENNZEICHEN' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='VERSIONSNUMMER' type='String' delimOptional='y' length='2' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='EDI-REFERENZNUMMER' type='String' delimOptional='y' length='14' strlenInChars='y' codepage='UTF-8'/>
<StructFormat name='SATZENDE' delim='\n' delimOptional='n'>
</StructFormat>
</StructFormat>
<StructFormat name='FV-ISR-SST-GROUP' delimOptional='n' repeat='150'>
<StructFormat name='F10-IDENTIFICATION-DATA' delimOptional='y'>
<FieldFormat name='F000-IDEN' type='String' delimOptional='y' length='2' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F010-TYPE' type='String' delimOptional='y' length='6' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F020-TIME' type='String' delimOptional='y' length='14' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F20-PRODUCTION-DATA' delimOptional='y'>
<FieldFormat name='F030-WAGO' type='String' delimOptional='y' length='12' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F040-FLAG' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F050-TRAI' type='String' delimOptional='y' length='17' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F060-CREA' type='String' delimOptional='y' length='8' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F070-WADA' type='String' delimOptional='y' length='12' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F080-FORA' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F090-FSCO' type='String' delimOptional='y' length='5' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F100-FSDE' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F110-INSR' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F120-INSC' type='String' delimOptional='y' length='5' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F130-INSD' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F140-FRON' type='String' delimOptional='y' length='3' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F150-DERA' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F160-DSTC' type='String' delimOptional='y' length='5' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F170-DSTD' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F180-REAL' type='String' delimOptional='y' length='12' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F190-TWEW' type='String' delimOptional='y' length='7' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F30-COMMERCIAL-DATA' delimOptional='y'>
<StructFormat name='F31-GOODS' delimOptional='y' repeat='4'>
<StructFormat name='F311-CONTAINER' delimOptional='y' repeat='4'>
<FieldFormat name='F240-SHGC' type='String' delimOptional='y' length='6' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F250-WEGC' type='String' delimOptional='y' length='7' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<FieldFormat name='F220-SFGC' type='String' delimOptional='y' length='6' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F230-NUGC' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F32-GOODS-DESC' delimOptional='y' repeat='4'>
<FieldFormat name='F260-WESH' type='String' delimOptional='y' length='7' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F270-RIDC' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F280-RIDG' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F290-HAIG' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F300-SUID' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F310-DALA' type='String' delimOptional='y' length='15' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<FieldFormat name='F200-TYTR' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F210-NUGO' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F40-CONTROL-LABEL-DATA' delimOptional='y'>
<FieldFormat name='F320-FORA' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F330-FOST' type='String' delimOptional='y' length='5' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F340-FOSN' type='String' delimOptional='y' length='5' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F350-FOSD' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F360-FODA' type='String' delimOptional='y' length='8' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F370-CRCO' type='String' delimOptional='y' length='6' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F380-CRDE' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F390-CECO' type='String' delimOptional='y' length='6' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F400-CEDE' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F410-CONU' type='String' delimOptional='y' length='6' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F50-ROUTE-DATA' delimOptional='y'>
<StructFormat name='F51-ROUTE-CODE' delimOptional='y' repeat='6'>
<FieldFormat name='F430-TRRY' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F440-FRON' type='String' delimOptional='y' length='2' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F450-ORDE' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<FieldFormat name='F420-RONU' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F60-BROKEN-WAGON-DATA' delimOptional='y'>
<FieldFormat name='F460-DADE' type='String' delimOptional='y' length='25' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F470-STDA' type='String' delimOptional='y' length='5' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F480-SDDA' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F490-DADA' type='String' delimOptional='y' length='12' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F500-DATY' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F70-CONS-NOTE-DATA' delimOptional='y'>
<StructFormat name='F71-CARRIER' delimOptional='y' repeat='20'>
<FieldFormat name='F710-CACO' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F720-CAST' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F730-CAPO' type='String' delimOptional='y' length='2' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F740-CAAC' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F72-COM-DEST-STAT' delimOptional='y'>
<FieldFormat name='F750-DSCC' type='String' delimOptional='y' length='2' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F760-DSSC' type='String' delimOptional='y' length='5' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F770-DSDE' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<FieldFormat name='F780-SWLT' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F790-CONT' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F80-LAST-EVENT-DATA' delimOptional='y'>
<FieldFormat name='F810-LEDD' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F820-LETY' type='String' delimOptional='y' length='2' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F830-LEDT' type='String' delimOptional='y' length='12' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F840-LECC' type='String' delimOptional='y' length='2' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F850-LESC' type='String' delimOptional='y' length='5' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F860-LEDE' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F870-LETR' type='String' delimOptional='y' length='6' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='F90-TRAIN-SITUATION-DATA' delimOptional='y'>
<FieldFormat name='F910-TRST' type='String' delimOptional='y' length='1' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F920-MPIM' type='String' delimOptional='y' length='4' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F930-MPCC' type='String' delimOptional='y' length='2' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F940-MPSC' type='String' delimOptional='y' length='5' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F950-MPSD' type='String' delimOptional='y' length='24' strlenInChars='y' codepage='UTF-8'/>
<FieldFormat name='F960-DTIM' type='String' delimOptional='y' length='6' strlenInChars='y' codepage='UTF-8'/>
</StructFormat>
<StructFormat name='SATZENDE' delim='\n' delimOptional='n'>
</StructFormat>
</StructFormat>
</MessageFormat>
Целевая структура должна быть:
<?xml version="1.0" encoding="UTF-8"?>
<WagonStatus_Fplv>
<K0-HEADER>
<SATZKOPF-K0 length="2" start="1"/>
<Externer_Partner length="35" start="3"/>
<INTERCHANGEREFERENZNUMMER length="14" start="38"/>
<NACHRICHTENREFERENZNUMMER length="14" start="52"/>
<NACHRICHTENTYP length="6" start="56">
<TESTKENNZEICHEN length="1" start="72"/>
<VERSIONSNUMMER length="2" start="73"/>
<EDI-REFERENZNUMMER length="14" start="75"/>
<SATZENDE/>
</K0-HEADER>
<FV-ISR-SST-GROUP>
<F10-IDENTIFICATION-DATA>
<F000-IDEN length="2" start="89"/>
<F010-TYPE length="6" start="91"/>
<F020-TIME length="14" start="97"/>
...
</WagonStatus_Fplv>
Таким образом, каждый FieldFormat в исходном документе будет отображаться как узел элемента с длинойв качестве атрибута, а начальный атрибут - это сумма длин предыдущих узлов элемента.И <StructFormat name='FV-ISR-SST-GROUP' delimOptional='n' repeat='150'>
означает, что эта структура будет повторяться 150 раз.
До сих пор с любезной помощью @Martin Hennen
У меня есть этот шаблон:
<?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" exclude-result-prefixes="#all" version="3.0">
<xsl:param name="msg" as="xs:string">H0 EVU_DBSRD PVG Z24 ABF-RF IR ExternalPartnerID_uuuuuuuuuuuuuuuuu0202017-03-16-07.27.40.864320NJNJ M1 80281261300008 M2 16.03.201707:27:00Z1 H62430 16.03.2017 16.03.201707:00:00+0027R1 00131800820664780201703154023641201703151159043706346965 000 JJ R1 02031800819657480201703154045545201703151159306557346965 000 NN </xsl:param>
<xsl:output method="xml" indent="yes"/>
<xsl:mode name="unroll" on-no-match="shallow-copy"/>
<xsl:strip-space elements="*"/>
<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:copy select="$this">
<xsl:apply-templates select="@* except @repeat, node()" mode="#current"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="repeat" select="count(tokenize($msg, $this/TagField/@value)) - 1"/>
<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="StructFormat[not(@repeat)]" mode="unroll">
<xsl:variable name="this" select="."/>
<xsl:choose>
<xsl:when test="$this/TagField and not(contains($msg, $this/TagField/@value)) ">
</xsl:when>
<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 mode="unroll"/>
</xsl:variable>
<xsl:template match="/">
<xsl:element name="{/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:element name="{@name}">
<!-- <xsl:attribute name="start" select="sum(preceding::FieldFormat/@length) /> -->
<xsl:attribute name="length" select="./@length"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Проблема заключается в том, когда я пытаюсьчтобы вычислить сумму предыдущих элементов, оператор (<xsl:attribute name="start" select="sum(preceding::FieldFormat/@length) />
) просто слишком дорог, так что механизм XSLT (Saxon 9.8 HE) не отвечает.Достигну ли я здесь предела мощности XSLT и должен ли я использовать другую технологию, такую как Java, для выполнения такого рода задач, или есть способ избежать этого дорогостоящего предыдущего выбора для улучшения производительности XSLT?