我最近問了這個問題,但是意識到我沒有很清楚地解釋它。 我有一個很大的.csv文件(8000+行),由發票組成,每個發票有多行。我將其解析爲XML結構,如下所示(簡化)。XSLT將大的單個父節點拆分成較小的子節點
輸入1 - $ XMLInput
<?xml version="1.0" encoding="UTF-8"?>
<root>
<row>
<invoiceNumber>1</invoiceNumber>
<invoiceText>invoice 1-1</invoiceText>
<position>1<position>
...
</row>
<row>
<invoiceNumber>1</invoiceNumber>
<invoiceText>invoice 1-2</invoiceText>
<position>2<position>
...
</row>
<row>
<invoiceNumber>2</invoiceNumber>
<invoiceText>invoice 2-1</invoiceText>
<position>3<position>
...
</row>
<row>
<invoiceNumber>2</invoiceNumber>
<invoiceText>invoice 2-2</invoiceText>
<position>4<position>
...
</row>
<row>
<invoiceNumber>3</invoiceNumber>
<invoiceText>invoice 3-1</invoiceText>
<position>5<position>
...
</row>
<row>
<invoiceNumber>3</invoiceNumber>
<invoiceText>invoice 3-2</invoiceText>
<position>6<position>
...
</row>
</roow>
輸入2 - $ maxBatchSize 描述:中斷到下一批次它變得比這個尺寸(常數)
輸入較大的後3 - $ listOfInvoices 描述:文檔中唯一發票編號的重複變量。例如:
<root>
<row>
<invoiceNumber>1</invoiceNumber>
</row>
<row>
<invoiceNumber>2</invoiceNumber>
</row>
<row>
<invoiceNumber>3</invoiceNumber>
</row>
</root>
爲了提高性能時間,我需要組這些元件由invoiceNumber,成批不大於x的每個節點(變量要導入)。從那裏我將每批發送到一個子處理器,而不是一次處理整個原始文檔。例如,在上面的例子中的XML文檔,如果批量大小可能不大於3,我需要以下XML輸出:
輸出1 - $ XMLOutput
<root>
<batch>
<row>
<invoiceNumber>1</invoiceNumber>
<invoiceText>invoice 1-1</invoiceText>
<position>1<position>
...
</row>
<row>
<invoiceNumber>1</invoiceNumber>
<invoiceText>invoice 1-2</invoiceText>
<position>2<position>
...
</row>
<row>
<invoiceNumber>2</invoiceNumber>
<invoiceText>invoice 2-1</invoiceText>
<position>3<position>
...
</row>
<row>
<invoiceNumber>2</invoiceNumber>
<invoiceText>invoice 2-2</invoiceText>
<position>4<position>
...
</row>
</batch>
<batch>
<row>
<invoiceNumber>3</invoiceNumber>
<invoiceText>invoice 3-1</invoiceText>
<position>5<position>
...
</row>
<row>
<invoiceNumber>3</invoiceNumber>
<invoiceText>invoice 3-2</invoiceText>
<position>6<position>
...
</row>
</batch>
</root>
這是一個要求,即所有發票的行在同一批中發送。我最初的XSLT嘗試是低於(2.0),我嘗試模擬一個while循環,通過遞歸調用模板,將發票組附加到當前節點。當達到最大批量時,我遞歸地調用批處理模板來創建一個新的批處理。我在每次遞歸調用之間傳遞發票和批處理計數器。
編輯:感謝肯的幫助我越來越近。我確實需要每次按行數劃分發票,而不是明確發票的數量。理論上,如果以下工作,我不知道如何確保發票號碼不存在於前面的兄弟節點中。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/" 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:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:variable name="batch-size" select="40" as="xs:integer"/>
<xsl:variable name="input" select="bpws:getVariableData('sortedInvoicesByBU')"/>
<xsl:key name="invoice-lines-by-invoice-number" match="row" use="invoiceNumber4z"/>
<xsl:template match="/">
<xsl:element name="batches">
<!--establish batches from possible non-contiguous invoice numbers-->
<xsl:for-each-group select="$input/*:UPSData/*:row" group-by="(position() - 1) idiv $batch-size">
<xsl:for-each select="distinct-values($input/*:UPSData/*:row/*:invoiceNumber4z)[not(.=preceding-sibling::item)]">
<xsl:element name="UPSData">
<xsl:for-each select="current()">
<xsl:for-each select="key('invoice-lines-by-invoice-number',.,$input)">
<!--copy rows as they are-->
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:for-each-group>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
再次謝謝你。我絕對同意我試圖採取一種程序化的方法,並迫使XSLT相應地適應它,只需要開始學習如何用功能語言進行思考。至於爲什麼我嘗試的編程方法不起作用,我會說這是因爲這不是它的設計方式。 – rwolters3
現在我想這是你幫助過的兩個問題,我一定會下載和學習你的書,看看你是否在我的領域有任何講座/課程,或者以前的講座的緩存版本。另外,我寫了一個小的錯字,我打算說8000或8千條記錄,而不是800萬,處理時間要快得多。 – rwolters3
我將我的StackOverflow配置文件更新爲即將發佈的講座系列或http://www.CraneSoftwrights.com/schedule.htm#calendar提供的信息。 在http://www.CraneSoftwrights.com/links/udemy-ptux-online.htm上,XSLT/XPath上有5個小時的免費流視頻講座,您甚至不需要設置用戶名即可只是自由觀看。 Udemy擁有可通過http://www.CraneSoftwrights.com/training/ptux/ptux-video.htm頁面購買的DVD流媒體版本。兩者都有完整答案的練習。獨立書沒有練習。 –