简体   繁体   English

使用xsl进行XSLT流式传输:迭代正确方法

[英]XSLT streaming with xsl:iterate correct way

I wanted to process a 161mo database, but java saxon9he run out of memory at 300mb of ram and the .NET at 1700mb ram, so I need to use streaming, so I use XMLSpy demo, but I still don't understand the xpath expressions child parent logic. 我想处理一个161mo数据库,但是java saxon9he在ram内存为300mb时内存不足,而在.net内存为1700mb时内存耗尽,因此我需要使用流传输,因此我使用XMLSpy演示,但我仍然不了解xpath表达式子父逻辑。 I am on windows xp sp3 32bit 4gb of ram. 我在Windows XP SP3 32bit 4GB RAM上。

    <xsl:iterate select="db_entry">
        <xsl:apply-templates select="db_entry"/>
    </xsl:iterate>

What the correct way to stream this with xsl:iterate or maybe xsl:for-each is sufficiente ? 用xsl:iterate或xsl:for-each进行流式传输的正确方法是什么? There is nearly 60000 entries in this database. 此数据库中有将近60000个条目。 I mean how to correctly write this because a db_entry within a db_entry does not work. 我的意思是如何正确编写此代码,因为db_entry中的db_entry不起作用。

EDIT: 编辑:

<xsl:template match="databank_export">
<xsl:iterate select="db_entry">
    <xsl:apply-templates select="public_data"/>
    <xsl:text> |</xsl:text>
    <xsl:apply-templates select="text_data"/>
    <xsl:text> |</xsl:text>
    <xsl:apply-templates select="research_data"/>
    <xsl:text>&#10;</xsl:text>
</xsl:iterate>
</xsl:template>

I replace the db_entry xsl:template by xsl:iterate but then XMLspy can't load the big file so it appears that streaming doesn't work. 我将db_entry xsl:template替换为xsl:iterate,但是XMLspy无法加载大文件,因此流似乎不起作用。 Am I doing it right or is it program limitations or demo limitations ? 我做对了还是程序限制还是演示限制?

2nd EDIT: I'll put here my entire xsl code: 第2次编辑:我将整个xsl代码放在这里:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 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" xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:err="http://www.w3.org/2005/xqt-errors" exclude-result-prefixes="array fn map math xhtml xs err" version="3.0">
    <xsl:output method="text" encoding="UTF-8" indent="yes"/>
    <xsl:mode streamable="yes"/>
    <!--
    <xsl:template match="databank_export">
    -->
    <xsl:template match="/">
        <xsl:apply-templates select="databank_export/copy-of(db_entry)" mode="entry"/>
    </xsl:template>
    <xsl:template match="db_entry" mode="entry">
        <xsl:value-of select="public_data, text_data, research_data" separator=" |"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>
    <xsl:template match="public_data">
        <xsl:value-of select="sflname"/>
        <xsl:text>; </xsl:text>
        <xsl:apply-templates select="bdata"/>
        <xsl:text>; </xsl:text>
        <xsl:value-of select="gender"/>
        <xsl:text>; PHOTO : |</xsl:text>
        <xsl:value-of select="name, gender, rating, datatype/@sdatatype, datatype/@sdatasource, bdata/sbdate, bdata/sbdate/@ccalendar" separator=" - "/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="bdata/sbtime, bdata/sbtime/@sbtime_ampm, bdata/sbtime/@ctimetype, bdata/sbtime/@stimetype, bdata/sbtime/@stmerid, bdata/sbtime/@ctzauto, bdata/sbtime/@jd_ut, bdata/sbtime/@sznabbr, bdata/sbtime/@time_unknown, bdata/sbtime/@itimeaac, bdata/sbtime/@stimeaac" separator=" "/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="bdata/place, bdata/country, bdata/country/@sctr" separator=", "/>
        <xsl:text>, </xsl:text>
        <xsl:value-of select="bdata/place/@slati, bdata/place/@slong" separator=" "/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="scollector, seditor, biographer" separator=" "/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="screationdate, slasteditdate" separator=" "/>
    </xsl:template>
    <xsl:template match="bdata">
        <xsl:value-of select="sbdate/@iday, sbdate/@imonth, sbdate/@iyear" separator="."/>
        <xsl:text>; </xsl:text>
        <xsl:value-of select="sbtime"/>
        <xsl:text>; </xsl:text>
        <xsl:analyze-string select="sbtime/@stmerid" regex="([hm]{{1}})([0-9]{{1,2}})([ew]{{1}})([0-9]{{0,2}})">
            <xsl:matching-substring>
                <xsl:choose>
                    <xsl:when test="regex-group(3) = 'e'">
                        <xsl:text>+</xsl:text>
                    </xsl:when>
                    <xsl:when test="regex-group(3) = 'w'">
                        <xsl:text>-</xsl:text>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text>+</xsl:text>
                    </xsl:otherwise>
                </xsl:choose>
                <xsl:choose>
                    <xsl:when test="regex-group(1) = 'h'">
                        <xsl:number value="regex-group(2)" format="01"/>
                    </xsl:when>
                    <xsl:when test="regex-group(1) = 'm'">
                        <xsl:text>00:</xsl:text>
                        <xsl:number value="regex-group(2)" format="01"/>
                        <xsl:text>:</xsl:text>
                        <xsl:number value="regex-group(4)" format="01"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text>+1</xsl:text>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:matching-substring>
        </xsl:analyze-string>
        <xsl:text>; </xsl:text>
        <xsl:value-of select="place, country" separator=","/>
        <xsl:text>; </xsl:text>
        <xsl:value-of select="place/@slati, place/@slong" separator="; "/>
    </xsl:template>
    <xsl:template match="text_data">
        <xsl:value-of select="shortbiography, wikipedia_link, db_link, sourcenotes" separator="|"/>
    </xsl:template>
    <xsl:template match="research_data">
        <xsl:apply-templates select="categories"/>
        <xsl:text>|</xsl:text>
        <xsl:apply-templates select="relationships"/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="events/@count"/>
        <xsl:text>|</xsl:text>
        <xsl:apply-templates select="events"/>
    </xsl:template>
    <xsl:template match="categories">
        <xsl:iterate select="category">
            <xsl:value-of select="@cat_id, @db_id, @catnotes" separator=" "/>
            <xsl:text> - </xsl:text>
            <xsl:value-of select="text()"/>
            <xsl:text> |</xsl:text>
        </xsl:iterate>
    </xsl:template>
    <xsl:template match="relationships">
        <xsl:iterate select="relationship">
            <xsl:value-of select="@rel_id, @rel_db_id, @db_id, @relcat" separator=" "/>
            <xsl:text> - </xsl:text>
            <xsl:value-of select="@relnotes, text()" separator=" - "/>
            <xsl:text> |</xsl:text>
        </xsl:iterate>
    </xsl:template>
    <xsl:template match="events">
        <xsl:iterate select="event">
            <xsl:value-of select="@sevcode, @evn_id, @db_id, @evnotes" separator=" "/>
            <xsl:text> |</xsl:text>
            <xsl:apply-templates select="event_data"/>
            <xsl:text> |</xsl:text>
        </xsl:iterate>
    </xsl:template>
    <xsl:template match="event">
        <xsl:apply-templates select="event_data"/>
    </xsl:template>
    <xsl:template match="event_data">
        <xsl:value-of select="sbdate, sbdate/@ccalendar, sbdate_dmy" separator=" "/>
    </xsl:template>

</xsl:stylesheet>

It work with a small sample file but not with the whole 161mb file. 它只能使用一个小的示例文件,但不能使用整个161mb的文件。

Best regards. 最好的祝福。

To give you a simple example, assuming you have lots of db_entry elements but we can safely assume that a single entry pulled into memory does not cause memory problems then you can use copy-of on those elements and use traditional processing in a different mode from the main mode using streaming: 为了给您提供一个简单的示例,假设您有很多db_entry元素,但是我们可以安全地假设将单个条目拉入内存不会引起内存问题,那么您可以对这些元素使用copy-of并以与使用流的主要模式:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:mode streamable="yes"/>

    <xsl:output method="text"/>

    <xsl:template match="/">
        <xsl:apply-templates select="databank_export/copy-of(db_entry)" mode="entry"/>
    </xsl:template>

    <xsl:template match="db_entry" mode="entry">
        <xsl:value-of select="public_data, text_data, research_data" separator=" |"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

That transforms eg 转变例如

<?xml version="1.0" encoding="UTF-8"?>
<databank_export>
   <db_entry>
      <public_data>public data 1</public_data>
      <text_data>text 1</text_data>
      <research_data>research 1</research_data>
   </db_entry>
   <db_entry>
      <public_data>public data 2</public_data>
      <text_data>text 2</text_data>
      <research_data>research 2</research_data>
   </db_entry>
   <db_entry>
      <public_data>public data 3</public_data>
      <text_data>text 3</text_data>
      <research_data>research 3</research_data>
   </db_entry>
   <db_entry>
      <public_data>public data 4</public_data>
      <text_data>text 4</text_data>
      <research_data>research 4</research_data>
   </db_entry>
   <db_entry>
      <public_data>public data 5</public_data>
      <text_data>text 5</text_data>
      <research_data>research 5</research_data>
   </db_entry>
   <db_entry>
      <public_data>public data 6</public_data>
      <text_data>text 6</text_data>
      <research_data>research 6</research_data>
   </db_entry>
   <db_entry>
      <public_data>public data 7</public_data>
      <text_data>text 7</text_data>
      <research_data>research 7</research_data>
   </db_entry>
   <db_entry>
      <public_data>public data 8</public_data>
      <text_data>text 8</text_data>
      <research_data>research 8</research_data>
   </db_entry>
   <db_entry>
      <public_data>public data 9</public_data>
      <text_data>text 9</text_data>
      <research_data>research 9</research_data>
   </db_entry>
   <db_entry>
      <public_data>public data 10</public_data>
      <text_data>text 10</text_data>
      <research_data>research 10</research_data>
   </db_entry>
</databank_export>

into

public data 1 |text 1 |research 1
public data 2 |text 2 |research 2
public data 3 |text 3 |research 3
public data 4 |text 4 |research 4
public data 5 |text 5 |research 5
public data 6 |text 6 |research 6
public data 7 |text 7 |research 7
public data 8 |text 8 |research 8
public data 9 |text 9 |research 9
public data 10 |text 10 |research 10

and Saxon 9.8 EE would use streaming. Saxon 9.8 EE将使用流式传输。

With xsl:iterate you could use 使用xsl:iterate可以使用

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:mode streamable="yes"/>

    <xsl:output method="text"/>

    <xsl:template match="/">
        <xsl:iterate select="databank_export/db_entry">
            <xsl:apply-templates select="copy-of()" mode="entry"/>
        </xsl:iterate>
    </xsl:template>

    <xsl:template match="db_entry" mode="entry">
        <xsl:value-of select="public_data, text_data, research_data" separator=" |"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

As for your extended stylesheet, still assuming that pulling a single db_entry into memory to process it normally with a mode that does not use streaming I think you want something along the lines of 至于您的扩展样式表,仍然假设将一个db_entry拉入内存以使用不使用流式传输的模式正常处理它,我想您需要遵循以下原则

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 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" xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:err="http://www.w3.org/2005/xqt-errors" exclude-result-prefixes="array fn map math xhtml xs err" version="3.0"
    default-mode="entry">
    <xsl:output method="text" encoding="UTF-8" indent="yes"/>
    <xsl:mode name="start" streamable="yes"/>
    <!--
    <xsl:template match="databank_export">
    -->
    <xsl:template match="/" mode="start">
        <xsl:apply-templates select="databank_export/copy-of(db_entry)" mode="entry"/>
    </xsl:template>
    <xsl:template match="db_entry">
        <xsl:apply-templates select="public_data, text_data, research_data"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>
    <xsl:template match="public_data">
        <xsl:value-of select="sflname"/>
        <xsl:text>; </xsl:text>
        <xsl:apply-templates select="bdata"/>
        <xsl:text>; </xsl:text>
        <xsl:value-of select="gender"/>
        <xsl:text>; PHOTO : |</xsl:text>
        <xsl:value-of select="name, gender, rating, datatype/@sdatatype, datatype/@sdatasource, bdata/sbdate, bdata/sbdate/@ccalendar" separator=" - "/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="bdata/sbtime, bdata/sbtime/@sbtime_ampm, bdata/sbtime/@ctimetype, bdata/sbtime/@stimetype, bdata/sbtime/@stmerid, bdata/sbtime/@ctzauto, bdata/sbtime/@jd_ut, bdata/sbtime/@sznabbr, bdata/sbtime/@time_unknown, bdata/sbtime/@itimeaac, bdata/sbtime/@stimeaac" separator=" "/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="bdata/place, bdata/country, bdata/country/@sctr" separator=", "/>
        <xsl:text>, </xsl:text>
        <xsl:value-of select="bdata/place/@slati, bdata/place/@slong" separator=" "/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="scollector, seditor, biographer" separator=" "/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="screationdate, slasteditdate" separator=" "/>
    </xsl:template>
    <xsl:template match="bdata">
        <xsl:value-of select="sbdate/@iday, sbdate/@imonth, sbdate/@iyear" separator="."/>
        <xsl:text>; </xsl:text>
        <xsl:value-of select="sbtime"/>
        <xsl:text>; </xsl:text>
        <xsl:analyze-string select="sbtime/@stmerid" regex="([hm]{{1}})([0-9]{{1,2}})([ew]{{1}})([0-9]{{0,2}})">
            <xsl:matching-substring>
                <xsl:choose>
                    <xsl:when test="regex-group(3) = 'e'">
                        <xsl:text>+</xsl:text>
                    </xsl:when>
                    <xsl:when test="regex-group(3) = 'w'">
                        <xsl:text>-</xsl:text>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text>+</xsl:text>
                    </xsl:otherwise>
                </xsl:choose>
                <xsl:choose>
                    <xsl:when test="regex-group(1) = 'h'">
                        <xsl:number value="regex-group(2)" format="01"/>
                    </xsl:when>
                    <xsl:when test="regex-group(1) = 'm'">
                        <xsl:text>00:</xsl:text>
                        <xsl:number value="regex-group(2)" format="01"/>
                        <xsl:text>:</xsl:text>
                        <xsl:number value="regex-group(4)" format="01"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text>+1</xsl:text>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:matching-substring>
        </xsl:analyze-string>
        <xsl:text>; </xsl:text>
        <xsl:value-of select="place, country" separator=","/>
        <xsl:text>; </xsl:text>
        <xsl:value-of select="place/@slati, place/@slong" separator="; "/>
    </xsl:template>
    <xsl:template match="text_data">
        <xsl:value-of select="shortbiography, wikipedia_link, db_link, sourcenotes" separator="|"/>
    </xsl:template>
    <xsl:template match="research_data">
        <xsl:apply-templates select="categories"/>
        <xsl:text>|</xsl:text>
        <xsl:apply-templates select="relationships"/>
        <xsl:text>|</xsl:text>
        <xsl:value-of select="events/@count"/>
        <xsl:text>|</xsl:text>
        <xsl:apply-templates select="events"/>
    </xsl:template>
    <xsl:template match="categories">
        <xsl:iterate select="category">
            <xsl:value-of select="@cat_id, @db_id, @catnotes" separator=" "/>
            <xsl:text> - </xsl:text>
            <xsl:value-of select="text()"/>
            <xsl:text> |</xsl:text>
        </xsl:iterate>
    </xsl:template>
    <xsl:template match="relationships">
        <xsl:iterate select="relationship">
            <xsl:value-of select="@rel_id, @rel_db_id, @db_id, @relcat" separator=" "/>
            <xsl:text> - </xsl:text>
            <xsl:value-of select="@relnotes, text()" separator=" - "/>
            <xsl:text> |</xsl:text>
        </xsl:iterate>
    </xsl:template>
    <xsl:template match="events">
        <xsl:iterate select="event">
            <xsl:value-of select="@sevcode, @evn_id, @db_id, @evnotes" separator=" "/>
            <xsl:text> |</xsl:text>
            <xsl:apply-templates select="event_data"/>
            <xsl:text> |</xsl:text>
        </xsl:iterate>
    </xsl:template>
    <xsl:template match="event">
        <xsl:apply-templates select="event_data"/>
    </xsl:template>
    <xsl:template match="event_data">
        <xsl:value-of select="sbdate, sbdate/@ccalendar, sbdate_dmy" separator=" "/>
    </xsl:template>

</xsl:stylesheet>

and then need to run Saxon 9.8 EE with -im:start . 然后需要使用-im:start运行Saxon 9.8 EE。 The above is basically the code you posted, only using default-mode="entry" to make sure all the templates and their apply-templates that you have written belong to the mode named entry while adding a streamable start mode which then uses my earlier suggestion of 上面基本上是您发布的代码,仅使用default-mode="entry"来确保您编写的所有模板及其应用模板都属于名为entry的模式,同时添加了可流start模式,然后使用我之前的的建议

    <xsl:template match="/" mode="start">
        <xsl:apply-templates select="databank_export/copy-of(db_entry)" mode="entry"/>
    </xsl:template>

to pull in the db_entry elements with streaming, but to push a copy of each to a non-streamable mode where normal processing can be used with eg 通过流db_entry元素,但是将每个副本的副本推入不可流模式,在这种模式下可以使用例如

    <xsl:template match="db_entry">
        <xsl:apply-templates select="public_data, text_data, research_data"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template

If I had written that from scratch I would have used the approach as in my shorter snippet to have the unnamed default mode as streamable and then to push the copies to a named, non-streamable mode but given all the code you had added it was easier to set that default-mode attribute and then use the named mode start with streaming as the initial mode. 如果我是从头开始编写的,那我将使用我的较短代码段中的方法,使未命名的默认模式为可流式,然后将副本推送到命名的不可流式模式,但是鉴于您添加的所有代码,更易于设置default-mode属性,然后使用命名模式, start与流作为初始模式。

As said, to work around memory problems, the whole approach with that mixture of streaming and traditional processing only makes sense if there are thousands of db_entry elements making up the size of the input tree with traditional processing. 如前所述,要解决内存问题,只有将成千上万个db_entry元素组成传统处理的输入树大小时,流和传统处理混合的整个方法才有意义。 And it needs Saxon 9.8 EE (or perhaps 9.7 EE) as the only current implementation of streaming. 而且它需要Saxon 9.8 EE(或者也许是9.7 EE)作为当前流的唯一实现。

Note that I have made no effort to check or correct all those templates you have posted, in general you could use xsl:for-each in many places where you have tried xsl:iterate or I would prefer there to use eg <xsl:apply-templates select="event"/> and set up an <xsl:template match="event">...</xsl:template> , to keep the code modular and the processing approach consistent. 请注意,我没有努力检查或更正所有已发布的模板,通常,您可以在尝试过xsl:iterate许多地方使用xsl:for-each ,或者我更喜欢在其中使用例如<xsl:apply-templates select="event"/>并设置<xsl:template match="event">...</xsl:template> ,以保持代码模块化和处理方法的一致性。

Martin has answered quite a lot of the questions, but let me add a few words. 马丁回答了很多问题,但让我补充几句话。

Your example code 您的示例代码

<xsl:iterate select="db_entry">
    <xsl:apply-templates select="db_entry"/>
</xsl:iterate>

seems to be a beginner's mistake: unless db_entry actually contains another db_entry element as a child, this should be 似乎是初学者的错误:除非db_entry实际上包含另一个db_entry元素作为子元素,否则应该是

<xsl:iterate select="db_entry">
    <xsl:apply-templates select="."/>
</xsl:iterate>

The difference between xsl:iterate and xsl:for-each is that with xsl:for-each , each item in the input sequence is processed independently of the others: there is no defined order of processing, and there is no way that the processing of one item can affect the way subsequent items are processed. xsl:iteratexsl:for-each之间的区别在于,使用xsl:for-each ,输入序列中的每个项目都是独立于其他项目进行处理的:没有定义的处理顺序,也没有办法处理一项可能会影响后续项的处理方式。 With xsl:iterate , the items are processed in order, and (by using xsl:next-iteration ) you can set variables/parameters when processing an item, which are available for use when processing the next item. 使用xsl:iterate可以按顺序处理项目,并且(通过使用xsl:next-iteration )可以在处理项目时设置变量/参数,这些变量/参数可以在处理下一个项目时使用。

This difference has nothing directly to do with streaming; 这种差异与流媒体没有直接关系。 however xsl:iterate was introduced because there were use cases (such as computing a running total on a bank account) that were very hard to make streamable without such a construct. 但是,引入xsl:iterate是因为存在一些用例(例如,计算银行帐户上的运行总额),如果没有这种构造,就很难使它们变得可流式处理。

Your edited code: 您编辑的代码:

<xsl:iterate select="db_entry">
    <xsl:apply-templates select="public_data"/>
    <xsl:text> |</xsl:text>
    <xsl:apply-templates select="text_data"/>
    <xsl:text> |</xsl:text>
    <xsl:apply-templates select="research_data"/>
    <xsl:text>&#10;</xsl:text>
</xsl:iterate>

could equally well be written using xsl:for-each , because the processing of an item doesn't depend in any way on the processing of previous items. 同样可以使用xsl:for-each编写,因为项目的处理完全不依赖于先前项目的处理。 Either way, however, it wouldn't satisfy the streaming rules, because you are making three "downward selections" within the iteration body, and you are only allowed one. 不管怎样,它都不满足流式传输规则,因为您在迭代主体中进行了三个“向下选择”,并且只允许一个。 The simplest workaround to this, as Martin has illustrated, is to make a copy of each db_entry (as a tree in memory) and then you can operate on this copy without any streaming constraints. 正如Martin所说明的,最简单的解决方法是为每个db_entry制作一个副本(作为内存中的树),然后您可以对该副本进行操作而不受任何流约束。

Another workaround, if you know that the three child elements occur in the order you are processing them, is to replace: 如果您知道三个子元素是按照处理它们的顺序出现的,则另一个解决方法是替换:

    <xsl:apply-templates select="public_data"/>
    <xsl:text> |</xsl:text>
    <xsl:apply-templates select="text_data"/>
    <xsl:text> |</xsl:text>
    <xsl:apply-templates select="research_data"/>
    <xsl:text>&#10;</xsl:text>

by 通过

        <xsl:for-each select="*[
            self::public_data or self::text_data or self::research_data]">
          <xsl:if test="position() ne 1"> |</xsl:if>
          <xsl:apply-templates select="."/>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>

(Note the little trick of putting a vertical bar before every entry except the first, rather than putting it after every entry except the last. That's because when you're streaming, you don't know when you're about to reach the end. Little things like this become very important when you're trying to make your code streamable.) (请注意,将竖线放置在除第一个条目之前的每个条目之前,而不是将除最后一个条目之外的每个条目之后放置一个小技巧。这是因为在流式传输时,您不知道何时到达终点当您尝试使代码可流式传输时,类似这样的小事情变得非常重要。)

As Martin says, Altova RaptorXML does not support streaming: you will need to use Saxon-EE for this. 正如Martin所说,Altova RaptorXML不支持流传输:您将需要为此使用Saxon-EE。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM