jjzjj

xml - XSLT 流与 xsl :iterate correct way

coder 2024-07-05 原文

我想处理一个 161mo 的数据库,但是 java saxon9he 在 300mb 内存和 .NET 在 1700mb 内存时内存不足,所以我需要使用流,所以我使用 XMLSpy 演示,但我仍然不明白xpath 表达式子父逻辑。我在 windows xp sp3 32 位 4gb 内存上。

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

使用 xsl:iterate 或 xsl:for-each 进行流式传输的正确方法是什么?该数据库中有近 60000 个条目。 我的意思是如何正确编写它,因为 db_entry 中的 db_entry 不起作用。

编辑:

<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>

我将 db_entry xsl:template 替换为 xsl:iterate,但随后 XMLspy 无法加载大文件,因此流式传输似乎不起作用。 我做得对还是程序限制或演示限制?

第二次编辑:我将把我的整个 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>

它适用于一个小样本文件,但不适用于整个 161mb 文件。

最好的问候。

最佳答案

Martin 已经回答了很多问题,但让我补充几句。

您的示例代码

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

似乎是初学者的错误:除非 db_entry 实际上包含另一个 db_entry 元素作为子元素,这应该是

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

xsl:iteratexsl:for-each 的区别在于,对于 xsl:for-each,输入中的每个项目sequence 独立于其他处理:没有定义的处理顺序,并且一个项目的处理不可能影响后续项目的处理方式。使用 xsl:iterate,项目按顺序处理,并且(通过使用 xsl:next-iteration)您可以在处理项目时设置变量/参数,这些变量/参数可用用于处理下一个项目。

这种差异与流媒体没有直接关系;然而,xsl:iterate 的引入是因为有些用例(例如计算银行账户的总计)如果没有这样的构造就很难实现流式传输。

您编辑的代码:

<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:for-each 编写,因为一个项目的处理不以任何方式依赖于先前项目的处理。然而,无论哪种方式,它都不满足流式规则,因为您在迭代主体中进行了三个“向下选择”,并且只允许一个。正如 Martin 所说明的那样,最简单的解决方法是为每个 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: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>

(请注意在除第一个条目之外的每个条目之前放置竖线的小技巧,而不是在除最后一个条目之外的每个条目之后放置竖线。这是因为在流式传输时,您不知道何时要到达终点。当你试图让你的代码流式传输时,像这样的小事情变得非常重要。)

正如 Martin 所说,Altova RaptorXML 不支持流式传输:为此您需要使用 Saxon-EE。

关于xml - XSLT 流与 xsl :iterate correct way,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45448452/

有关xml - XSLT 流与 xsl :iterate correct way的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby-on-rails - 如何在 Rails 3 中禁用 XML 解析 - 2

    我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::

  3. ruby - 如何使用 Nokogiri::XML::Builder 生成动态标签? - 2

    我正在遍历数组中的一组标签名称,我想使用构建器打印每个标签名称,而不是求助于“我认为:builder=Nokogiri::XML::Builder.newdo|xml|fortagintagsxml.tag!tag,somevalendend会这样做,但它只是创建名称为“tag”的标签,并将标签变量作为元素的文本值。有人可以帮忙吗?这个看起来应该比较简单,我刚刚在搜索引擎上找不到答案。我可能没有以正确的方式提问。 最佳答案 尝试以下操作。如果我没记错的话,我添加了一个根节点,因为Nokogiri需要一个。builder=Nokogi

  4. ruby - 如何让 Nokogiri 解析并返回 XML 文档? - 2

    这是一些奇怪的例子:#!/usr/bin/rubyrequire'rubygems'require'open-uri'require'nokogiri'print"withoutread:",Nokogiri(open('http://weblog.rubyonrails.org/')).class,"\n"print"withread:",Nokogiri(open('http://weblog.rubyonrails.org/').read).class,"\n"运行此返回:withoutread:Nokogiri::XML::Documentwithread:Nokogiri::

  5. ruby - 模式加载时出现 Nokogiri::XML::Schema SyntaxError - 2

    我正在尝试加载SAML协议(protocol)架构(具体来说:https://www.oasis-open.org/committees/download.php/3407/oasis-sstc-saml-schema-protocol-1.1.xsd),但在执行此操作之后:schema=Nokogiri::XML::Schema(File.read('saml11_schema.xsd'))我得到这个输出:Nokogiri::XML::SyntaxErrorException:Element'{http://www.w3.org/2001/XMLSchema}element',att

  6. ruby-on-rails - 来自 cucumber 的 HTTP POST XML 内容 - 2

    我正在尝试通过POST将XML内容发送到一个简单的Rails项目中的Controller(“解析”)方法(“索引”)。它不是RESTful,因为我的模型名称不同,比如“汽车”。我在有效的功能测试中有以下内容:deftest_index...data_file_path=File.dirname(__FILE__)+'/../../app/views/layouts/index.xml.erb'message=ERB.new(File.read(data_file_path))xml_result=message.result(binding)doc=REXML::Document.ne

  7. ruby - 如何使用 XPath 和 Nokogiri 获取 XML 节点的内容 - 2

    我有这样的代码:@doc=Nokogiri::HTML(open(url)@doc.xpath(query).eachdo|html|putshtml#howgetcontentofanodeend我如何获取节点的内容而不是像这样: 最佳答案 这是READMEfile中的概要示例为Nokogiri展示了一种使用CSS、XPath或混合的方法:require'nokogiri'require'open-uri'#GetaNokogiri::HTML:Documentforthepagewe’reinterestedin...doc=N

  8. ruby - 使用 Ruby 向网络服务器发送 XML 请求 - 2

    恐怕我没有太多通过网络服务器发布文档(例如XML)的经验,所以如果我对HTTP的理解不足,我深表歉意。我在127.0.0.1上的ruby​​应用程序中设置了一个基本的MongrelWeb服务器端口2000.(服务器)。我在同一台计算机上运行一个单独的Ruby应用程序。(客户)。我需要客户端向服务器发送XML文档。我曾尝试使用Net::HTTP来执行此操作,但我找不到一个明确的示例来告诉我应该做什么。我试过了,但遇到了错误。我已将请求分解,使其尽可能基本:http=Net::HTTP.new("127.0.0.1",2000)http.post('file','query=foo')#x

  9. ruby - 如何使用 Sinatra 提供 XML 文档? - 2

    我有一些XML文档,我想从Sinatra服务器获取这些文档。我做了一些搜索,但找不到任何具体的东西。我确实找到了构建器gem,但我不想从头开始构建文档。我试着做这样的事情get'/'xml='Myname90'bodyxmlend但这会在它周围添加HTML标签。这可能是我所缺少的非常基本的东西。你能给我指出正确的方向吗? 最佳答案 这对于Sinatra来说非常简单:get'/'docontent_type'text/xml'"Luis99"end在获取“/”时,响应将是XML"Luis99"使用正确的content_type。

  10. ruby - 尝试使用 nokogiri 获取 xml 文件中 cdata 标签内的内容 - 2

    我已经看到了几件事,但到目前为止似乎没有任何效果。我正在使用nokogirionrails3ruby​​1.9.2通过url解析xml。xml的片段如下所示:我正在尝试解析它以获取与NewsLineText关联的文本r=node.at_xpath('.//newslinetext')ifnode.at_xpath('.//newslinetext')s=node.at_xpath('.//newslinetext').textifnode.at_xpath('.//newslinetext')t=node.at_xpath('.//newslinetext').contentifnod

随机推荐