xsl:将文本转换为xml

科马甘

我正在进行文本2 xml转换,我需要将以下纯文本转换为xml

[header]
CODE VEND = ABCD
TYPE = ORDER
CL CDE = ABDEFGH
CL INV = ABDEFGH
DAT CDE = 03022020
EMAIL = abcd@ .fr
NO CDE = 0000042268
DAT LIV = 03022020
TYP CDE = CDE SPECIALE
NBLIN = 1
CONTRM = ABDEFGH
CL LIV = ABDEFGH
[LINE]
REF VEN = DEFGH
EAN = 123456789
QTE = 1
REF CUST = "AZERTYUOP      "
[end]

我当前的xsl如下:

<xsl:stylesheet 
  version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="txt-encoding" as="xs:string" select="'iso-8859-1'"/>
  <xsl:param name="txt-uri" as="xs:string" select="'linktofile'"/>

  <xsl:template match="/" name="text2xml">
    <xsl:variable name="txt" select="unparsed-text($txt-uri, $txt-encoding)"/>
    <xsl:variable name="entries" as="node()*">
      <xsl:analyze-string select="$txt" regex="\r\n?|\n">
        <xsl:non-matching-substring>
          <xsl:analyze-string select="." regex="([^;]*).*=([^;]*)">
            <xsl:matching-substring>
              <entry>
                <nom><xsl:value-of select="normalize-space(regex-group(1))"/>
                </nom>
                <valeur><xsl:value-of select="normalize-space(regex-group(2))"/>
                </valeur>
                <!--text2><xsl:value-of 
                  select="normalize-space(regex-group(3))"/></text2-->
              </entry>
            </xsl:matching-substring>
          </xsl:analyze-string>
        </xsl:non-matching-substring>
      </xsl:analyze-string>
    </xsl:variable>
    <results>
      <xsl:for-each-group select="$entries" group-by="nom">
        <xsl:copy-of
          select="current-group()[1]/nom,current-group()/*[not(self::nom)]"/>
      </xsl:for-each-group>
    </results>
  </xsl:template>

</xsl:stylesheet>

我能够在等号上拆分数据,我需要以下内容:

<CODE_VEND>ABCD</CODE_VEND>
<TYPE>ORDER</TYPE>
<CL_CDE>ABCD</CL_CDE>

+根据以下信息将标题(在[HEADER]和CL_LIV之间)分组 <NO_CDE>0000042268</NO_CDE>

你能帮我吗

谢谢

更新描述

[ENTETE]
CODE VEND = MONH
TYPE = COMMANDE
CL CDE = ABDCDEFG
CL INV = HIJIKL
DAT CDE = 03022020
EMAIL = [email protected]
NO CDE = 0000042268
DAT LIV = 03022020
TYP CDE = CDE SPECIALE
NBLIN = 3
CONTRM = ABDCDEFG
CL LIV = ABDCDTERK
[LIGNE]
REF FOU = REFVEN1
GENCOD = EAN11111111
QTE = 1
REF CLI = "XXXXXXXXXXX      "
[LIGNE]
REF FOU = REFVEN2
GENCOD = EAN2222222
QTE = 1
REF CLI = "YYYYYYYYYYYYYYY      "
[LIGNE]
REF FOU = REFVEN3
GENCOD = EAN333333
QTE = 1
REF CLI = "ZZZZZZZZZZZZZZZ      "
[FIN]

目标

<ORDER>
    <CODE_VEND>MONH</CODE_VEND>
    <TYPE>COMMANDE</TYPE>
    <CL_CDE>ABDCDEFG</CL_CDE>
    <CL_INV>HIJIKL</CL_INV>
    <DAT_CDE>03022020</DAT_CDE>
    <EMAIL>[email protected]</EMAIL>
    <NO_CDE>0000042268</NO_CDE>
    <DAT_LIV>03022020</DAT_LIV>
    <TYP_CDE>CDE SPECIALE</TYP_CDE>
    <NBLIN>3</NBLIN>
    <CONTRM>ABDCDEFG</CONTRM>
    <CL_LIV>ABDCDTERK</CL_LIV>
    <LINE>
        <REF_VEN>REFVEN1</REF_VEN>
        <EAN>EAN11111111</EAN>
        <QTE>1</QTE>
        <REF_CLI>XXXXXXXXXXX</REF_CLI>
    </LINE>
    <LINE>
        <REF_VEN>REFVEN2</REF_VEN>
        <EAN>EAN2222222</EAN>
        <QTE>1</QTE>
        <REF_CLI>YYYYYYYYYYYYYYY</REF_CLI>
    </LINE>
    <LINE>
        <REF_VEN>REFVEN3</REF_VEN>
        <EAN>EAN333333</EAN>
        <QTE>1</QTE>
        <REF_CLI>ZZZZZZZZZZZZZZZ</REF_CLI>
    </LINE>
</ORDER>

...

马丁·洪恩

使用XSLT 3可以将其作为一个分组任务,用来对文本文件中的行进行分组group-starting-with,然后可以通过以下方式将每一行分解为一个元素analyze-string

<xsl:stylesheet 
  version="3.0" 
  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"
  exclude-result-prefixes="#all">

  <xsl:output indent="yes"/>

  <xsl:mode on-no-match="shallow-skip"/>

  <xsl:param name="txt-encoding" as="xs:string" select="'iso-8859-1'"/>
  <xsl:param name="txt-uri" as="xs:string" select="'linktofile'"/>

  <xsl:template match="/" name="text2xml">

    <xsl:variable name="lines" as="xs:string*" select="unparsed-text-lines($txt-uri, $txt-encoding)"/>

    <xsl:for-each-group select="$lines" group-starting-with=".[. = '[ENTETE]']">
        <ORDER>
            <xsl:for-each-group select="tail(current-group())" group-starting-with=".[. = '[LIGNE]']">
                <xsl:choose>
                    <xsl:when test=". = '[LIGNE]'">
                        <LINE>
                            <xsl:apply-templates select="(current-group() => tail()) ! analyze-string(., '(.+) = (.+)')"/>
                        </LINE>                        
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="(current-group() => tail()) ! analyze-string(., '(.+) = (.+)')"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </ORDER>
    </xsl:for-each-group>
  </xsl:template>

  <xsl:template match="fn:match">
      <xsl:element name="{replace(normalize-space(fn:group[@nr = 1]), ' ', '_')}">
          <xsl:value-of select="normalize-space(fn:group[@nr = 2])"/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

带有内联文本数据的在线示例位于https://xsltfiddle.liberty-development.net/bEzknsy

XSLT 3在Saxon 9.8或更高版本或AltovaXML 2017 R3或更高版本中可用。

如果只有XSLT 2,则当然可以使用第一步,您必须将文本行转换为XML元素,然后group-starting-with对这些元素使用类似的内容。当然,analyze-string除了功能之外,您还可以坚持使用xsl:analyze-string

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章