Разбор строки с XSLT, содержащей несколько типов - PullRequest
0 голосов
/ 09 января 2019

У меня есть строка, которая может содержать несколько кодов, например, LP или 1S. По сути, мне нужно иметь возможность искать в этой строке список значений (LP | 1S).

Эти значения всегда являются переменными, и если появляется определенный код, мне нужно добавить подстроку после него, чтобы получить дополнительные данные в соответствии с определенным отображением.

Например, после LP указывается тип (LP), неделя (1), дата, автобус (0800) и местоположение (1884).

См. Код ниже:

Я думал об использовании if ... содержит LP, затем подстроку. Тем не менее, я могу только подстроки один раз в тексте. Могу ли я использовать a для каждого из них и продолжать подстроку до конца строки?

LP12018122908001884CA212345LP120181229080018841S12345

<root>
  <entry>
   <type>LP</type>
   <week>1</week>
   <date>20181229</date>
   <location>08001884</location>
  <entry>
  <entry>
   <type>CA</type>
   <week>2</week>
   <location>212345</location>
  <entry>
  <entry>
   <type>LP</type>
   <week>1</week>
   <date>20181229</date>
   <location>08001884</location>
  <entry>
  <entry>
   <type>1S</type>
   <location>12345</location>
  <entry>
</root>

1 Ответ

0 голосов
/ 09 января 2019

Предполагается, что мы говорим о разборе фиксированной ширины ввода:

Это легко сделать в XSLT 2.0 с помощью регулярных выражений и xsl:analyze-string:

XML

<input>LP12018122908001884LP22018122908001884LP72018122908001884</input>

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
    <output>
        <xsl:analyze-string select="input" regex="(.{{2}})(.)(.{{8}})(.{{8}})">
            <xsl:matching-substring>
                <entry>
                    <type><xsl:value-of select="regex-group(1)"/></type>
                    <week><xsl:value-of select="regex-group(2)"/></week>
                    <date><xsl:value-of select="regex-group(3)"/></date>
                    <location><xsl:value-of select="regex-group(4)"/></location>
                </entry>
            </xsl:matching-substring>
        </xsl:analyze-string>
    </output>
</xsl:template>

</xsl:stylesheet>

Результат

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <entry>
      <type>LP</type>
      <week>1</week>
      <date>20181229</date>
      <location>08001884</location>
   </entry>
   <entry>
      <type>LP</type>
      <week>2</week>
      <date>20181229</date>
      <location>08001884</location>
   </entry>
   <entry>
      <type>LP</type>
      <week>7</week>
      <date>20181229</date>
      <location>08001884</location>
   </entry>
</output>

Демо : http://xsltransform.hikmatu.com/3NzcBsL


Сделать то же самое в XSLT 1.0 немного сложнее:

XSLT 1.0

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

<xsl:template match="/">
    <root>
        <xsl:call-template name="create-entries">
            <xsl:with-param name="string" select="input"/>
        </xsl:call-template>
    </root>
</xsl:template>

<xsl:template name="create-entries">
    <xsl:param name="string"/>
    <xsl:variable name="entry" select="substring($string, 1, 19)" />
    <entry>
        <type><xsl:value-of select="substring($entry, 1, 2)"/></type>
        <week><xsl:value-of select="substring($entry, 3, 1)"/></week>
        <date><xsl:value-of select="substring($entry, 4, 8)"/></date>
        <location><xsl:value-of select="substring($entry, 13, 8)"/></location>
    </entry>
    <xsl:if test="string-length($string) > 19">
        <!-- recursive call -->
        <xsl:call-template name="create-entries">
            <xsl:with-param name="string" select="substring($string, 20)" />
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

Демо: http://xsltransform.hikmatu.com/3NzcBsL/1

...