加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

高速XSLT从XML转换为CSV

发布时间:2020-12-16 05:36:12 所属栏目:百科 来源:网络整理
导读:我一直在尝试使用XSLT在最有效的时间从 XML文档中获取CSV数据. 以下是我的示例XML ?xml version="1.0" encoding="ISO-8859-1"? sObjects xmlns="urn:sobject.partner.soap.sforce.com" sObject NameRaagu/Name BillingStreetHoskote/BillingStreet/sObject s
我一直在尝试使用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() &lt; last()">
                        <xsl:value-of select="$delimiter" />
                    </xsl:if>
                </xsl:for-each>

                <xsl:text>&#xa;    </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() &lt; last()">
                <xsl:value-of select="$delimiter" />
            </xsl:if>
        </xsl:for-each>
        <xsl:if test="position() &lt; last()">
            <xsl:text>&#xa;    </xsl:text>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

从功能的角度来看,上面的XSLT工作得非常好.
但我正在尝试处理大约10000条记录. i,在sObject元素上有10000个实例,每个sObject将包含大约15个字段.

如果我在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() &lt; 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分钟,我不认为我已经确定了真正的问题是什么.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读