微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

XSLT 3.0 中映射和查找的使用

如何解决XSLT 3.0 中映射和查找的使用

我是 XSLT 3.0 的新手,我正在探索 xslt 映射和累加器以满足我的一项要求。我有一个输入聚合 XML,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Aggregate>
   <File>
       <Info>
           <emplid>0081781</emplid>
           <Number>12345_A</Number>
       </Info>        
        
         
       <Info>
           <emplid>009892</emplid> 
           <Number>12345_B</Number>
       </Info>   
    
        <Info>
           <emplid>0044371</emplid>
           <Number>12345_C</Number>
       </Info>  
   </File>


   <Employee_Data>        
       <Employee>            
           <emplid>0081781</emplid>            
           <empl_Status>A</empl_Status>
       </Employee>
    
       <Employee>            
           <emplid>009892</emplid>
           <empl_Status>T</empl_Status>
       </Employee>
    
   </Employee_Data>
</Aggregate>

预期结果:

<Root>
   <Output_Data>
       <Employee>
           <emplid>0081781</emplid>            
           <empl_Status>A</empl_Status>
           <Number>12345_A</Number>
       </Employee>
    
       <Employee>
           <emplid>009892</emplid>
           <empl_Status>T</empl_Status>
           <Number>12345_B</Number>
       </Employee>
   </Output_Data>
</Root>

虽然这看起来像 <File> 元素上一个相当简单的基于 xsl:key 的解决方案,但我希望找到一个带有 XSLT 3.0 的流解决方案,因为数据量非常大,我想避免高我的环境中的内存消耗。

感谢任何帮助!

解决方法

据我所知,带流的 XSLT 3 仅受 Saxon EE 支持,因此您可以让您的生活变得轻松并依靠扩展在流期间捕获节点:

<?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:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:saxon="http://saxon.sf.net/"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">
    
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    
    <xsl:mode on-no-match="shallow-copy" streamable="yes" use-accumulators="infos"/>
    
    <xsl:accumulator name="infos" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
        <xsl:accumulator-rule saxon:capture="yes" phase="end"
            match="Info"
            select="map:put($value,string(emplid),string(Number))"/>
    </xsl:accumulator>
    
    <xsl:template match="File"/>
    
    <xsl:template match="Aggregate">
        <Root>
            <xsl:apply-templates/> 
        </Root>
    </xsl:template>
    
    <xsl:template match="Employee_Data">
        <Output_Data>
            <xsl:apply-templates/>
        </Output_Data>
    </xsl:template>
    
    <xsl:template match="Employee">
        <xsl:apply-templates select="copy-of()" mode="burst"/>
    </xsl:template>
    
    <xsl:mode name="burst" on-no-match="shallow-copy"/>
    
    <xsl:template match="Employee" mode="burst">
        <xsl:copy>
            <xsl:apply-templates/>
            <Number>{accumulator-before('infos')(string(emplid))}</Number>
        </xsl:copy>
    </xsl:template>
    
</xsl:stylesheet>

但是,我不确定在哪个版本(Saxon EE 的 9.9 或 10)引入了 saxon:capture 机制。

要在没有 Saxon 扩展的情况下完成此操作,我将使用两个累加器,一个用于存储 id,第二个用于构建地图:

<xsl:accumulator name="emp-id" as="xs:string?" initial-value="()" streamable="yes">
    <xsl:accumulator-rule match="file/Info/emplid/text()" select="normalize-space()"/>
</xsl:accumulator>

<xsl:accumulator name="Employees" as="map(xs:string,xs:string)" streamable="yes" initial-value="map{}">
    <xsl:accumulator-rule match="file/Info/Number/text()" select="map:put($value,accumulator-before('emp-id'),normalize-space())"/>
</xsl:accumulator>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。