首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过xslt2将大型文本文件转换为xml的性能问题

通过xslt2将大型文本文件转换为xml的性能问题
EN

Stack Overflow用户
提问于 2017-12-08 13:15:25
回答 2查看 212关注 0票数 0

我试图使用xslt 2转换将文本文件转换为xml文件。

这是文本文件的内容:

代码语言:javascript
复制
0000000001  0000000001  ED  I   I       1900-01-01  I   VAT000000000000 BE  1   A       CO      S       451     LD      1010    Stanford
0000000002  0000000002  ED  I   I       1900-01-01  I   VAT000000000000 BE  1   A       CO      S       451     LD      1010    Stanford
0000000003  0000000003  ED  I   I       1900-01-01  I   VAT000000000000 BE  1   A       CO      S       451     LD      1010    Stanford

这些列由“制表”键(选项卡)分隔。有些列为空,但使用一个选项卡键将该列与其他列分隔开来。因此,我使用了regex来完成这个任务( regex不是一个简化的形式,但我认为它可以优化)

这是我的XSLT文件:

代码语言:javascript
复制
<?xml version="1.1" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
    xmlns:xsi="setClients.xsd"
    exclude-result-prefixes="xs xd"
    version="2.0">

    <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="'file:///xxxxxxx.txt'"/>

    <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="(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)">
                    <xsl:matching-substring>
                        <entry>

                            <!-- * infos client -->
                            <c_id><xsl:value-of select="regex-group(1)"/></c_id>
                            <c_shipo_id><xsl:value-of select="normalize-space(regex-group(2))"/></c_shipo_id>
                            <c_company_id><xsl:value-of select="normalize-space(regex-group(3))"/></c_company_id>
                            <c_type_client><xsl:value-of select="normalize-space(regex-group(4))"/></c_type_client>
                            <c_classe><xsl:value-of select="normalize-space(regex-group(5))"/></c_classe>
                            <c_sous_type_client><xsl:value-of select="normalize-space(regex-group(6))"/></c_sous_type_client>
                            <c_start_date><xsl:value-of select="normalize-space(regex-group(7))"/></c_start_date>
                            <c_type_personne><xsl:value-of select="normalize-space(regex-group(8))"/></c_type_personne>
                            <c_type_personne><xsl:value-of select="normalize-space(regex-group(10))"/></c_type_personne>
                            <c_type_document><xsl:value-of select="normalize-space(regex-group(11))"/></c_type_document>
                            <c_num_tva><xsl:value-of select="normalize-space(regex-group(12))"/></c_num_tva>
                            <c_pays><xsl:value-of select="normalize-space(regex-group(13))"/></c_pays>
                            <c_pays_id><xsl:value-of select="normalize-space(regex-group(14))"/></c_pays_id>
                            <c_raison_sociale><xsl:value-of select="normalize-space(regex-group(15))"/></c_raison_sociale>
                            <c_civilité><xsl:value-of select="normalize-space(regex-group(16))"/></c_civilité>
                            <c_name><xsl:value-of select="normalize-space(regex-group(17))"/></c_name>
                            <c_prenom><xsl:value-of select="normalize-space(regex-group(18))"/></c_prenom>
                            <c_complement><xsl:value-of select="normalize-space(regex-group(19))"/></c_complement>
                            <c_adresse_forcee><xsl:value-of select="normalize-space(regex-group(20))"/></c_adresse_forcee>
                            <c_complement_adr><xsl:value-of select="normalize-space(regex-group(21))"/></c_complement_adr>
                            <c_numero><xsl:value-of select="normalize-space(regex-group(22))"/></c_numero>
                            <c_complement_numero><xsl:value-of select="normalize-space(regex-group(23))"/></c_complement_numero>
                            <c_adresse_rue><xsl:value-of select="normalize-space(regex-group(24))"/></c_adresse_rue>
                            <c_lieu_dit><xsl:value-of select="normalize-space(regex-group(25))"/></c_lieu_dit>
                            <c_code_postal><xsl:value-of select="normalize-space(regex-group(26))"/></c_code_postal>
                            <c_localite><xsl:value-of select="normalize-space(regex-group(27))"/></c_localite>
                            <c_telephone><xsl:value-of select="normalize-space(regex-group(28))"/></c_telephone>
                            <c_telephone_mobile><xsl:value-of select="normalize-space(regex-group(29))"/></c_telephone_mobile>
                            <c_email><xsl:value-of select="normalize-space(regex-group(30))"/></c_email>
                            <c_fax><xsl:value-of select="normalize-space(regex-group(31))"/></c_fax>
                            <c_actif><xsl:value-of select="normalize-space(regex-group(32))"/></c_actif>
                            <c_date_creation><xsl:value-of select="normalize-space(regex-group(33))"/></c_date_creation>
                            <c_langue><xsl:value-of select="normalize-space(regex-group(34))"/></c_langue>
                            <c_sapcode><xsl:value-of select="normalize-space(regex-group(35))"/></c_sapcode>
                            <c_invoicecopies><xsl:value-of select="normalize-space(regex-group(36))"/></c_invoicecopies>
                            <c_flttax><xsl:value-of select="normalize-space(regex-group(37))"/></c_flttax>
                            <c_flttax1><xsl:value-of select="normalize-space(regex-group(38))"/></c_flttax1>
                            <c_flttax2><xsl:value-of select="normalize-space(regex-group(39))"/></c_flttax2>
                            <c_flttax3><xsl:value-of select="normalize-space(regex-group(40))"/></c_flttax3>
                            <c_fldistax><xsl:value-of select="normalize-space(regex-group(41))"/></c_fldistax>
                            <c_equaladressbilling><xsl:value-of select="normalize-space(regex-group(42))"/></c_equaladressbilling>
                            <c_equaladressinvoice><xsl:value-of select="normalize-space(regex-group(43))"/></c_equaladressinvoice>
                            <c_equaladresspayment><xsl:value-of select="normalize-space(regex-group(44))"/></c_equaladresspayment>
                            <c_collectiontype><xsl:value-of select="normalize-space(regex-group(45))"/></c_collectiontype>
                            <c_companycode><xsl:value-of select="normalize-space(regex-group(46))"/></c_companycode>
                            <c_collectionid><xsl:value-of select="normalize-space(regex-group(47))"/></c_collectionid>
                            <c_duedatefree><xsl:value-of select="normalize-space(regex-group(48))"/></c_duedatefree>
                            <c_payements><xsl:value-of select="normalize-space(regex-group(49))"/></c_payements>
                            <c_paynum><xsl:value-of select="normalize-space(regex-group(50))"/></c_paynum>
                            <c_iban><xsl:value-of select="normalize-space(regex-group(51))"/></c_iban>
                            <c_mandate><xsl:value-of select="normalize-space(regex-group(52))"/></c_mandate>
                            <c_mandatedate><xsl:value-of select="normalize-space(regex-group(53))"/></c_mandatedate>
                            <c_expdate><xsl:value-of select="normalize-space(regex-group(54))"/></c_expdate>
                            <c_securitycode><xsl:value-of select="normalize-space(regex-group(55))"/></c_securitycode>
                            <c_authornum><xsl:value-of select="normalize-space(regex-group(56))"/></c_authornum>
                            <c_cardtype><xsl:value-of select="normalize-space(regex-group(57))"/></c_cardtype>
                            <c_bank><xsl:value-of select="normalize-space(regex-group(58))"/></c_bank>
                            <c_fixedue><xsl:value-of select="normalize-space(regex-group(59))"/></c_fixedue>
                            <c_duelastday><xsl:value-of select="normalize-space(regex-group(60))"/></c_duelastday>
                            <c_dateini><xsl:value-of select="normalize-space(regex-group(61))"/></c_dateini>
                            <c_datefin><xsl:value-of select="normalize-space(regex-group(62))"/></c_datefin>
                            <c_compfactid><xsl:value-of select="normalize-space(regex-group(63))"/></c_compfactid>
                            <c_persontype><xsl:value-of select="normalize-space(regex-group(64))"/></c_persontype>

                            <!-- * infos ptv -->

                            <p_id><xsl:value-of select="normalize-space(regex-group(65))"/></p_id>
                            <p_type><xsl:value-of select="normalize-space(regex-group(66))"/></p_type>
                            <p_useguide><xsl:value-of select="normalize-space(regex-group(67))"/></p_useguide>
                            <p_controldelivery><xsl:value-of select="normalize-space(regex-group(68))"/></p_controldelivery>
                            <p_copiesinitonclose><xsl:value-of select="normalize-space(regex-group(69))"/></p_copiesinitonclose>
                            <p_nominative><xsl:value-of select="normalize-space(regex-group(70))"/></p_nominative>
                            <p_sapcode><xsl:value-of select="normalize-space(regex-group(71))"/></p_sapcode>
                            <p_pays><xsl:value-of select="normalize-space(regex-group(72))"/></p_pays>
                            <p_raison_sociale><xsl:value-of select="normalize-space(regex-group(73))"/></p_raison_sociale>
                            <p_civilite><xsl:value-of select="normalize-space(regex-group(74))"/></p_civilite>
                            <p_nom><xsl:value-of select="normalize-space(regex-group(75))"/></p_nom>
                            <p_prenom><xsl:value-of select="normalize-space(regex-group(76))"/></p_prenom>
                            <p_complement><xsl:value-of select="normalize-space(regex-group(77))"/></p_complement>
                            <p_adresse_forcee><xsl:value-of select="normalize-space(regex-group(78))"/></p_adresse_forcee>
                            <p_complement_adr><xsl:value-of select="normalize-space(regex-group(79))"/></p_complement_adr>
                            <p_numero><xsl:value-of select="normalize-space(regex-group(80))"/></p_numero>
                            <p_complement_numero><xsl:value-of select="normalize-space(regex-group(81))"/></p_complement_numero>
                            <p_adresse_rue><xsl:value-of select="normalize-space(regex-group(82))"/></p_adresse_rue>
                            <p_lieu_dit><xsl:value-of select="normalize-space(regex-group(83))"/></p_lieu_dit>
                            <p_code_postal><xsl:value-of select="normalize-space(regex-group(84))"/></p_code_postal>
                            <p_localite><xsl:value-of select="normalize-space(regex-group(85))"/></p_localite>
                            <p_telephone><xsl:value-of select="normalize-space(regex-group(86))"/></p_telephone>
                            <p_telephone_mobile><xsl:value-of select="normalize-space(regex-group(87))"/></p_telephone_mobile>
                            <p_email><xsl:value-of select="normalize-space(regex-group(88))"/></p_email>
                            <p_fax><xsl:value-of select="normalize-space(regex-group(89))"/></p_fax>
                            <p_deliverydays><xsl:value-of select="normalize-space(regex-group(90))"/></p_deliverydays>
                            <p_active><xsl:value-of select="normalize-space(regex-group(91))"/></p_active>
                            <p_gestamp><xsl:value-of select="normalize-space(regex-group(92))"/></p_gestamp>
                            <p_numamp><xsl:value-of select="normalize-space(regex-group(93))"/></p_numamp>
                            <p_numcasieramp><xsl:value-of select="normalize-space(regex-group(94))"/></p_numcasieramp>
                            <p_numboxamp><xsl:value-of select="normalize-space(regex-group(95))"/></p_numboxamp>
                            <p_distributeur><xsl:value-of select="normalize-space(regex-group(96))"/></p_distributeur>
                            <p_enseigneamp><xsl:value-of select="normalize-space(regex-group(97))"/></p_enseigneamp>
                            <p_typeamp><xsl:value-of select="normalize-space(regex-group(98))"/></p_typeamp>
                            <zero><xsl:value-of select="normalize-space(regex-group(99))"/></zero>

                        </entry>

                    </xsl:matching-substring>
                </xsl:analyze-string>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:variable>

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

        <clients>
            <xsl:for-each select="$entries">
                <client>
                    <xsl:attribute name="companyID">
                        <xsl:value-of select="c_company_id"/>
                    </xsl:attribute>
                    <xsl:attribute name="clientID" >
                        <xsl:value-of select="c_id"/>
                    </xsl:attribute>
                    <general>
                        <xsl:attribute name="startDate">
                            <xsl:value-of select="c_start_date"/>
                        </xsl:attribute>
                        <xsl:attribute name="country">
                            <xsl:value-of select="c_pays_id"/>
                        </xsl:attribute>
                        <xsl:attribute name="clientType">
                            <xsl:value-of select="c_type_client"/>
                        </xsl:attribute>
                        <xsl:attribute name="clientSubtype">
                            <xsl:value-of select="c_sous_type_client"/>
                        </xsl:attribute>
                        <xsl:attribute name="clientClass">
                            <xsl:value-of select="c_classe"/>
                        </xsl:attribute>
                    </general>
                </client>


            </xsl:for-each>     
        </clients>
    </xsl:template>
</xsl:stylesheet>

因此,当我根据这个xslt文件(在氧气XML编辑器上执行)生成一个XML时,当列数小于20时,需要1秒才能完成。当我添加一些O列时,就会出现延迟,我应该等待15秒以上才能生成XML文件。这对我来说是件坏事,因为我需要处理XSLT文件中的99列。

你能告诉我为什么那里的表演有问题吗?我该怎么办?任何建议都能帮到我。

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-11 16:20:04

基于我们在注释中的交换,我认为您可以尝试使用tokenize而不是xsl:analyze-string来将输入解析为行,然后将行解析为列,看看效果是否更好。

使用tokenize的示例是

代码语言:javascript
复制
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">

   <xsl:variable name="tsv" as="xs:string">0000000001  0000000001  ED  I   I       1900-01-01  I   VAT000000000000 BE  1   A       CO      S       451     LD      1010    Stanford
0000000002  0000000002  ED  I   I       1900-01-01  I   VAT000000000000 BE  1   A       CO      S       451     LD      1010    Stanford
0000000003  0000000003  ED  I   I       1900-01-01  I   VAT000000000000 BE  1   A       CO      S       451     LD      1010    Stanford</xsl:variable>

   <xsl:output indent="yes"/>

   <xsl:variable name="lines" as="xs:string*" select="tokenize($tsv, '\r?\n')[normalize-space()]"/>
   <xsl:variable name="entries" as="node()*">

                    <xsl:for-each select="$lines">
                        <xsl:for-each select="tokenize(., '\s+')"><!-- if the input is really tab separated we need '\t' as the second argument for tokenize -->
                            <entry>
                                <col pos="{position()}">
                                    <xsl:value-of select="normalize-space()"/>
                                </col>
                            </entry>
                        </xsl:for-each>
                    </xsl:for-each>

    </xsl:variable>

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

        <clients>
           <xsl:copy-of select="$entries"/>

            <xsl:for-each select="$entries">
                <client>
                    <xsl:attribute name="companyID">
                        <xsl:value-of select="c_company_id"/>
                    </xsl:attribute>
                    <xsl:attribute name="clientID" >
                        <xsl:value-of select="c_id"/>
                    </xsl:attribute>
                    <general>
                        <xsl:attribute name="startDate">
                            <xsl:value-of select="c_start_date"/>
                        </xsl:attribute>
                        <xsl:attribute name="country">
                            <xsl:value-of select="c_pays_id"/>
                        </xsl:attribute>
                        <xsl:attribute name="clientType">
                            <xsl:value-of select="c_type_client"/>
                        </xsl:attribute>
                        <xsl:attribute name="clientSubtype">
                            <xsl:value-of select="c_sous_type_client"/>
                        </xsl:attribute>
                        <xsl:attribute name="clientClass">
                            <xsl:value-of select="c_classe"/>
                        </xsl:attribute>
                    </general>
                </client>


            </xsl:for-each>     
        </clients>
    </xsl:template>
</xsl:transform>

,它只生成相同的列名,以适应自定义列名使用

代码语言:javascript
复制
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">

   <xsl:variable name="tsv" as="xs:string">0000000001  0000000001  ED  I   I       1900-01-01  I   VAT000000000000 BE  1   A       CO      S       451     LD      1010    Stanford
0000000002  0000000002  ED  I   I       1900-01-01  I   VAT000000000000 BE  1   A       CO      S       451     LD      1010    Stanford
0000000003  0000000003  ED  I   I       1900-01-01  I   VAT000000000000 BE  1   A       CO      S       451     LD      1010    Stanford</xsl:variable>

   <xsl:output indent="yes"/>

   <xsl:variable name="lines" as="xs:string*" select="tokenize($tsv, '\r?\n')[normalize-space()]"/>
   <xsl:variable name="entries" as="node()*">

                    <xsl:for-each select="$lines">

                            <entry>
                            <xsl:variable name="columns" select="tokenize(., '\s+')"/><!-- if the input is really tab separated we need '\t' as the second argument for tokenize -->
                          <c_id><xsl:value-of select="$columns[1]"/></c_id>
                            <c_shipo_id><xsl:value-of select="$columns[2]"/></c_shipo_id>
                            <c_company_id><xsl:value-of select="$columns[3]"/></c_company_id>
                            </entry>

                    </xsl:for-each>

    </xsl:variable>

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

        <clients>

            <xsl:for-each select="$entries">
                <client>
                    <xsl:attribute name="companyID">
                        <xsl:value-of select="c_company_id"/>
                    </xsl:attribute>
                    <xsl:attribute name="clientID" >
                        <xsl:value-of select="c_id"/>
                    </xsl:attribute>
                    <general>
                        <xsl:attribute name="startDate">
                            <xsl:value-of select="c_start_date"/>
                        </xsl:attribute>
                        <xsl:attribute name="country">
                            <xsl:value-of select="c_pays_id"/>
                        </xsl:attribute>
                        <xsl:attribute name="clientType">
                            <xsl:value-of select="c_type_client"/>
                        </xsl:attribute>
                        <xsl:attribute name="clientSubtype">
                            <xsl:value-of select="c_sous_type_client"/>
                        </xsl:attribute>
                        <xsl:attribute name="clientClass">
                            <xsl:value-of select="c_classe"/>
                        </xsl:attribute>
                    </general>
                </client>


            </xsl:for-each>     
        </clients>
    </xsl:template>
</xsl:transform>

联机示例位于http://xsltransform.hikmatu.com/bFukv8fhttp://xsltransform.hikmatu.com/bFukv8f/1,用于将列标记为相邻的选项卡字符,以指示空列使用tokenize(., '\t')

票数 1
EN

Stack Overflow用户

发布于 2017-12-12 12:52:22

我认为性能问题几乎肯定在正则表达式中。

代码语言:javascript
复制
regex="(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)"

它表现不佳的原因是它有高度的模糊性,因此回溯。

请记住,.*将匹配尽可能多的字符-包括选项卡。因此,它将开始吞咽整行,然后意识到这不会导致匹配,然后回溯直到它找到一个制表符字符,然后意识到这再次失败,等等。最简单的解决方法是将每个(.*)替换为([^\t]*) (即,除制表符之外的任何字符的序列)。但是,正如@MartinHonnen建议的那样,在选项卡上标记为分隔符要简单得多。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47715158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档