小组&使用结果文档拆分xml文件,无法正常工作

时间:2017-11-09 07:32:18

标签: xml xslt split saxon

我正在寻找您的帮助来分组和拆分我的MxML文件。

下面是我的示例XML,我想将其分组并拆分成多个块。 我的MxML文件有多个ccy对和成熟度集。当我整个处理文件时需要花费一些时间,因此想法是成对分组并将文件分成多个较小的块(可配置)。

数据文件... xml

<?xml version="1.0"?>
<GuiRoot>
    <xc:XmlCache xmlns:xc="XmlCache" xc:action="Update">
        <xc:XmlCacheArea xc:value="MarketParameters">
            <mp:nickName xmlns:mp="mx.MarketParameters" xc:value="./BORATES" xc:subset="Reference">
                <mp:date xc:value="TODAY">
                    <fx:forex xmlns:fx="mx.MarketParameters.Forex">
                        <fxsm:smile xmlns:fxsm="mx.MarketParameters.Forex.Smile">
                            <fxsm:pair xc:value="pair1">
                                <fxsm:maturity xc:value="10Y">
                                    <fxsm:ordinate xc:type="Fields" xc:value="10.000000000">
                                        <mp:bid xc:type="Field" xc:keyFormat="N">0.9236</mp:bid>
                                        <mp:ask xc:type="Field" xc:keyFormat="N">0.9236</mp:ask>
                                    </fxsm:ordinate>
                                </fxsm:maturity>
                                <fxsm:maturity xc:value="1Y">
                                    <fxsm:ordinate xc:type="Fields" xc:value="90.000000000">
                                        <mp:bid xc:type="Field" xc:keyFormat="N">3.4369</mp:bid>
                                        <mp:ask xc:type="Field" xc:keyFormat="N">3.4369</mp:ask>
                                    </fxsm:ordinate>
                                </fxsm:maturity>
                            </fxsm:pair>
                            <fxsm:pair xc:value="pair2">
                                <fxsm:maturity xc:value="10Y">
                                    <fxsm:ordinate xc:type="Fields" xc:value="10.000000000">
                                        <mp:bid xc:type="Field" xc:keyFormat="N">3.4369</mp:bid>
                                        <mp:ask xc:type="Field" xc:keyFormat="N">3.4369</mp:ask>
                                    </fxsm:ordinate>
                                </fxsm:maturity>
                                <fxsm:maturity xc:value="1Y">
                                    <fxsm:ordinate xc:type="Fields" xc:value="90.000000000">
                                        <mp:bid xc:type="Field" xc:keyFormat="N">3.4369</mp:bid>
                                        <mp:ask xc:type="Field" xc:keyFormat="N">3.4369</mp:ask>
                                    </fxsm:ordinate>
                                </fxsm:maturity>
                            </fxsm:pair>
                            <fxsm:pair xc:value="pair3">
                                <fxsm:maturity xc:value="10Y">
                                    <fxsm:ordinate xc:type="Fields" xc:value="10.000000000">
                                        <mp:bid xc:type="Field" xc:keyFormat="N">3.4369</mp:bid>
                                        <mp:ask xc:type="Field" xc:keyFormat="N">3.4369</mp:ask>
                                    </fxsm:ordinate>
                                </fxsm:maturity>
                                <fxsm:maturity xc:value="1Y">
                                    <fxsm:ordinate xc:type="Fields" xc:value="90.000000000">
                                        <mp:bid xc:type="Field" xc:keyFormat="N">3.4369</mp:bid>
                                        <mp:ask xc:type="Field" xc:keyFormat="N">3.4369</mp:ask>
                                    </fxsm:ordinate>
                                </fxsm:maturity>
                            </fxsm:pair>
                            <fxsm:pair xc:value="pair4">
                                <fxsm:maturity xc:value="10Y">
                                    <fxsm:ordinate xc:type="Fields" xc:value="10.000000000">
                                        <mp:bid xc:type="Field" xc:keyFormat="N">3.4369</mp:bid>
                                        <mp:ask xc:type="Field" xc:keyFormat="N">3.4369</mp:ask>
                                    </fxsm:ordinate>
                                </fxsm:maturity>
                                <fxsm:maturity xc:value="1Y">
                                    <fxsm:ordinate xc:type="Fields" xc:value="90.000000000">
                                        <mp:bid xc:type="Field" xc:keyFormat="N">3.4369</mp:bid>
                                        <mp:ask xc:type="Field" xc:keyFormat="N">3.4369</mp:ask>
                                    </fxsm:ordinate>
                                </fxsm:maturity>
                            </fxsm:pair>
                        </fxsm:smile>
                    </fx:forex>
                </mp:date>
            </mp:nickName>
        </xc:XmlCacheArea>
    </xc:XmlCache>
</GuiRoot>

我的XSLT(不工作)

<?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"  
xmlns:fxsm="mx.MarketParameters.Forex.Smile"
xpath-default-namespace="mx.MarketParameters.Forex.Smile"  xmlns:xc="xmlCache" exclude-result-prefixes="xs math" version="2.0">
   <xsl:output method="xml" version="1.0" omit-xml-declaration="no" encoding="UTF-8" indent="yes"/>
   <!--  <xsl:mode on-no-match="shallow-copy"/> -->
   <xsl:strip-space elements="*"/>
   <!-- define variables  [start] -->
   <xsl:variable name="noOfSplits" select="3"/>
   <!-- define variables  [end] -->
   <!--- an alternative to shallow-copy in xslt 2.0 -->
   <xsl:template match="@* | node()">
      <xsl:copy>
         <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
   </xsl:template>
   <!--- an alternative to shallow-copy in xslt 2.0 -->
   <xsl:template match="/">
      <xsl:variable name="original-root-element" select="*"/>
      <xsl:variable name="groups">
         <xsl:for-each-group select="//pair" group-by="@xc:value">
            <xsl:copy>
               <xsl:copy-of select="@*"/>
               <xsl:for-each-group select="current-group()/maturity" group-by="@xc:value">
                  <xsl:copy>
                     <xsl:copy-of select="@*, current-group()/node()"/>
                  </xsl:copy>
               </xsl:for-each-group>
            </xsl:copy>
         </xsl:for-each-group>
      </xsl:variable>
      <xsl:for-each-group select="$groups/pair" group-by="(position() - 1) mod $noOfSplits">
         <xsl:result-document href="files/split{position()}.xml">
            <xsl:apply-templates select="$original-root-element">
               <xsl:with-param name="contents" select="current-group()" tunnel="yes"/>
            </xsl:apply-templates>
         </xsl:result-document>
      </xsl:for-each-group>
   </xsl:template>
   <xsl:template match="//smile">
      <xsl:param name="contents" tunnel="yes"/>
      <xsl:copy>
         <xsl:copy-of select="$contents"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

请善意帮助您了解上述代码的错误....

提前致谢

1 个答案:

答案 0 :(得分:1)

我会告诉你我的调试过程,而不仅仅是给你答案。希望这会更有启发性。

首先,我使用-t选项从命令行运行转换。除了XML声明之外,它在控制台上没有产生输出,并且-t输出没有显示正在写入的任何辅助输出文件。

然后我使用-T选项运行(通常会产生非常大量的跟踪输出)。这次它产生了一个非常短的跟踪文件:

<trace saxon-version="9.8.0.6" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <source node="/" line="0" file="test.xml">
  <xsl:template match="/" line="20" column="29" module="test.xsl">
   <xsl:variable name="original-root-element" line="21" column="64" module="test.xsl">
    <xsl:variable name="groups" line="22" column="37" module="test.xsl">
     <xsl:for-each-group line="23" column="70" module="test.xsl">
     </xsl:for-each-group>
     <xsl:for-each-group line="34" column="95" module="test.xsl">
     </xsl:for-each-group>
    </xsl:variable>
   </xsl:variable>
  </xsl:template>
 </source><!-- / -->
</trace>

这表示第23行的xsl:for-each-group未选择任何内容。我通过显示变量$ groups的值的xsl:message确认了这一点。

我尝试更改select表达式以明确使用名称空间(select="//Q{mx.MarketParameters.Forex.Smile}pair"),这没有任何区别。

然后我在oXygen中尝试了相同的XPath表达式//Q{mx.MarketParameters.Forex.Smile}pair,并选择了四个pair元素。

我尝试//*:pair.//*:pair以及.//*:smile/* - 仍然没有运气。

我在for-each-groups之前添加了<xsl:message select=".//*:pair"/>,并输出了四个pair元素。

啊哈!另一个原因是for-each-group可以产生空输出:它选择元素OK,但它们没有分组键。分组键是@xc:value,它似乎存在于源文档中。但是,如果我们仔细查看,源文档会xmlns:xc="XmlCache",而样式表会xmlns:xc="xmlCache"

所以,一个简单的错误。正如本练习所示,这些可能很难确定。唯一真正的答案是使用模式感知的XSLT编码 - 这可能允许XSLT编译器发现错误。可悲的是,人们意识到这一点的唯一一次就是他们花了几个小时来调试这样的问题,而那时他们已经做了太多的事情来投入时间来确保它不会再次发生。