我尝试使用xslt 2转换将文本文件转换为xml文件。
这是文本文件的内容:
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
这些列由" tabulation"分隔。键(标签)。某些列为空,但使用Tab键将此列与其他列分开。所以我使用正则表达式来做这个(正则表达式不是简化形式,但我认为它可以优化)
这是我的XSLT文件:
<?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时,当列数<&lt;时,需要一秒钟来完成这些操作。 20.当我添加其他列时,会出现延迟,我应该等待超过15秒才能生成XML文件。这对我来说是件坏事,因为我需要在我的XSLT文件中处理99列。
你能告诉我为什么那里有性能问题吗? 我该怎么办? 任何建议都可以帮助我。
感谢。
答案 0 :(得分:2)
我认为性能问题几乎肯定在正则表达式中
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所建议的那样,将标签作为分隔符标记为更简单。
答案 1 :(得分:1)
根据我们在评论中的交流,我认为您可以尝试使用tokenize
而不是xsl:analyze-string
来替换方法,将输入解析为行,然后将行解析为列,看看是否表现更好。
使用tokenize的示例是
<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>
只需生成相同的列名称,即可根据自定义列名进行调整
<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/bFukv8f和http://xsltransform.hikmatu.com/bFukv8f/1,用于标记相邻标签字符指示空列使用tokenize(., '\t')
的列。