【问题标题】:group & split xml file using result-document, not working使用结果文档对 xml 文件进行分组和拆分,不起作用
【发布时间】:2017-11-09 07:32:18
【问题描述】:

我正在寻求您对我的 Mxml 文件进行分组和拆分的帮助。

下面是我的示例 XML,我想在其中分组并拆分为多个块。 我的 Mxml 文件有多个 ccy 对和成熟度集。当我将文件作为一个整体处理时,它需要一些时间,所以想法是成对分组并将文件分成多个较小的 chuk(这将是可配置的)。

数据文件...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>

请您帮助了解上述代码有什么问题......

提前致谢

【问题讨论】:

  • 好吧,您必须将输入缩短为演示问题所需的最小数据,然后您需要显示该输入所需的结果。简单地告诉我们 XSLT“不工作”并不能解释您想要哪个结果以及为什么您编写或复制了呈现的 XSLT,它似乎试图对各种元素进行分组。另外,当您提到 Saxon 并想要拆分文件时,也许使用 Saxon 9.8 和 XSLT 3 会使您的任务更轻松,请参阅xslt-3-by-example.blogspot.de/2017/06/…
  • 请不要告诉我们什么“不起作用”。我们需要知道它是如何失败的。
  • 嗨,马丁,感谢您的回复......
  • 抱歉不清楚,我的互联网连接看起来有些问题,我的评论没有正确提交......我正在使用 saxon-he-9.4.0.7.jar。是的,我想根据 fxsm:pair 的值拆分文件。我希望 files/split0.xml pair1 & pair4 中的 pair3 在 files/split1.xml 中,而 pair2 在 files/split2.xml 中

标签: xml xslt split saxon


【解决方案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-group 之前添加了一个 &lt;xsl:message select=".//*:pair"/&gt;,它会输出四个 pair 元素。

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

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

【讨论】:

  • 非常感谢迈克尔,这非常有用。然而,在我的 xslt... xmlns:xc="XmlCache" 进行更改后,它仍然没有生成任何文件...
  • @PanduranG,我已经尝试了您发布的样式表,其中包含 Michael 建议的针对您使用 Saxon 9 和 -t 选项的输入的修复,它显示它写入了三个结果文件 files/split1.xmlfiles/split2.xml , files/split3.xml.
  • @MartinHonnen,我用的是 saxon-he-9.4.0.7.jar,你用的一样吗?您应用的修复是否仅在行下方? w3.org/1999/XSL/Transform" xmlns:xs="w3.org/2001/XMLSchema" xmlns:math="w3.org/2005/xpath-functions/math" xmlns:xc="XmlCache" xmlns:fxsm="mx.MarketParameters.Forex.Smile " xpath-default-namespace="mx.MarketParameters.Forex.Smile" exclude-result-prefixes="xs math" version="2.0">
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-14
  • 2016-04-02
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 2015-04-29
相关资源
最近更新 更多