高速XSLT从XML转换为CSV
我一直在尝试使用XSLT在最有效的时间从
XML文档中获取CSV数据.
以下是我的示例XML <?xml version="1.0" encoding="ISO-8859-1"?> <sObjects xmlns="urn:sobject.partner.soap.sforce.com"> <sObject> <Name>Raagu</Name> <BillingStreet>Hoskote</BillingStreet> </sObject> <sObject> <Name>Rajath</Name> <BillingStreet>BTM</BillingStreet> <age>25</age> </sObject> <sObject> <Name>Sarath</Name> <BillingStreet>Murgesh</BillingStreet> <location>Bangalore</location> <age>#N/A</age> </sObject> <sObject> <Name>Bharath</Name> <BillingStreet>EGL</BillingStreet> <location>Bangalore</location> <shipping>Hoskote</Shipping> </sObject> <sObject> <Id>12312321321</Id> <Name>Guru</Name> <location>Sirsi</location> <date>12-12-12</date> </sObject> <sObject> <Name>Appa</Name> <BillingStreet>someStrrt</BillingStreet> <accountNo>213213</accountNo> </sObject> <sObject> <Name>Sarath</Name> <BillingStreet>Murgesh</BillingStreet> <location>Bangalore</location> </sObject> <sObject> <Name>Sarath</Name> <BillingStreet>Murgesh</BillingStreet> <location>Bangalore</location> </sObject> <sObject> <Name>Sarath</Name> <BillingStreet>Murgesh</BillingStreet> <location>Bangalore</location> </sObject> 我想要这种输出 <?xml version="1.0" encoding="utf-8"?><csv xmlns="http://www.approuter.com/schemas/RootNode"><data>Name,BillingStreet,age,location,Shipping,Id,date,accountNo Raagu,Hoskote,Rajath,BTM,25,Sarath,Murgesh,#N/A,Bangalore,Bharath,EGL,Guru,Sirsi,12312321321,12-12-12,Appa,someStrrt,213213 Sarath,</data></csv> 为了完成这项工作,我尝试了以下XSLT <xsl:stylesheet version="1.0" xmlns:p0="urn:sobject.partner.soap.sforce.com" xmlns:csv="csv:csv" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output encoding="utf-8" method="xml"/> <xsl:strip-space elements="*" /> <xsl:variable name="delimiter" select="','"/> <xsl:key name="field" match="p0:sObject/*" use="name()"/> <!-- variable containing the first occurrence of each field --> <xsl:variable name="allFields" select="/*/*/*[generate-id()=generate-id(key('field',name())[1])]"/> <xsl:template match="/"> <!-- Output the CSV header --> <xsl:element name="csv" namespace="http://www.approuter.com/schemas/RootNode"> <xsl:element name="data" namespace="http://www.approuter.com/schemas/RootNode"> <xsl:for-each select="$allFields"> <xsl:value-of select="name()" /> <xsl:if test="position() < last()"> <xsl:value-of select="$delimiter" /> </xsl:if> </xsl:for-each> <xsl:text>
 </xsl:text> <xsl:apply-templates select="/*/p0:sObject" /> </xsl:element> </xsl:element> </xsl:template> <xsl:template match="p0:sObject"> <xsl:variable name="this" select="." /> <xsl:for-each select="$allFields"> <xsl:value-of select="$this/*[name() = name(current())]" /> <xsl:if test="position() < last()"> <xsl:value-of select="$delimiter" /> </xsl:if> </xsl:for-each> <xsl:if test="position() < last()"> <xsl:text>
 </xsl:text> </xsl:if> </xsl:template> </xsl:stylesheet> 从功能的角度来看,上面的XSLT工作得非常好. 如果我在XSLT上面运行它来处理这么多记录,它就会折腾. XSLT大约需要20分钟来处理和提供csv数据.我想在几秒钟内完成这项工作.也就是说,XSLT需要3-4秒才能处理10k条记录(sObject条目)以提供有效的CSV数据,如上所示. 这是我坚持增强XSLT并需要帮助修改此XSLT以更快地工作的地方.
一些建议:
>如果您使用的是XSLT 2.0处理器,请不要设置version =“1.0”.这使它以向后兼容模式运行,这涉及更多的运行时检查. <xsl:for-each select="$allFields"> <xsl:value-of select="name()" /> <xsl:if test="position() < last()"> <xsl:value-of select="$delimiter" /> </xsl:if> </xsl:for-each> 如果position()!= 1,则在项目之前插入分隔符,而不是在position()!= last()之后在项目之后插入分隔符,总是更好.那是因为last()是一项涉及前瞻的昂贵操作.在这种简单的情况下,整个事情可以被替换 <xsl:value-of select="$allFields/name()" separator="{$delimiter}"/> >如果你只想使用一次键,那么定义一个键是没有意义的.查找唯一字段名称最好使用distinct-values(/ * / * / * / name()). 但是,我真的看不出为什么这需要20分钟,我不认为我已经确定了真正的问题是什么. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |