首页 > 解决方案 > XSLT3 查找值问题 | 流媒体

问题描述

我有一个合并的报告数据(数据来自两个来源)作为输入文件,我需要根据一个键查找一个值。目前我的代码返回错误的查找值。由于预计输入数据的大小会很大,因此我想使用流式传输以获得更好的性能。

这是我的输入 xml

  1. 元素Number'是查找的关键。Xpath is'批次/工人/编号'
  2. Phone基于Number' . Xpath isMergedOutput/Data/Row/Phone的查找元素

样本输入

<?xml version="1.0" encoding="UTF-8"?> 
<MergedOutput>
    <Data>
        <Row>
            <Employee_Batch_Id>12567</Employee_Batch_Id>
            <Phone>FirstEmp8013457896</Phone>
            <Assignment_Id>5046150263</Assignment_Id>
        </Row>
        <Row>
            <Employee_Batch_Id>12568</Employee_Batch_Id>
            <Phone>SecondEmp7853457896</Phone>
            <Assignment_Id>5046150263</Assignment_Id>
        </Row>
    </Data>
    <Batch>
        <Workers>
            <Number>12567</Number>
            <Contact>Work7864532890</Contact>
        </Workers>
        <Workers>
            <Number>12568</Number>
            <Contact>Work6782340167</Contact>
        </Workers>
    </Batch>
</MergedOutput>

当前的 XSLT3 代码

<?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"          
    exclude-result-prefixes="xs r1 r2 map"
    version="3.0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="#all"/>

    <xsl:accumulator name="FirstReportLookupValuePhone" as="xs:string" initial-value="''" streamable="yes">
        <xsl:accumulator-rule match="Phone/text()" select="."/>
    </xsl:accumulator>

    <xsl:accumulator name="EmployeeIDLookup" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
        <xsl:accumulator-rule match="Employee_Batch_Id/text()" select="map:put($value, string(.), accumulator-before('FirstReportLookupValuePhone'))"/>
    </xsl:accumulator>    
        <xsl:template match="Batch">
            <Workers>
            <xsl:apply-templates select="Workers"/>
            </Workers>
        </xsl:template>

    <xsl:template match="Workers">
        <xsl:variable name="vWorkers" select="copy-of()"/>
        <xsl:variable name="vMappedWorker" select="accumulator-after('EmployeeIDLookup')( normalize-space($vWorkers/Number))"/>
        <Worker>
        <WorkerID><xsl:value-of select="$vWorkers/Number"/></WorkerID>
        <Work_Contact_Number><xsl:value-of select="$vWorkers/Contact"/></Work_Contact_Number>
        <Home_Contact_Number><xsl:value-of select="$vMappedWorker"/></Home_Contact_Number>
        </Worker>

    </xsl:template>


</xsl:stylesheet>

电流输出

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
    <Worker>
        <WorkerID>12567</WorkerID>
        <Work_Contact_Number>Work7864532890</Work_Contact_Number>
        <Home_Contact_Number/> <!-- Value is empty, Expected value is FirstEmp8013457896 -->
    </Worker>
    <Worker>
        <WorkerID>12568</WorkerID>
        <Work_Contact_Number>Work6782340167</Work_Contact_Number>
        <Home_Contact_Number>FirstEmp8013457896</Home_Contact_Number> <!-- Incorrect Value, Expected value is SecondEmp7853457896 -->
    </Worker>
</Workers>

预期产出

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
   <Worker>
      <WorkerID>12567</WorkerID>
      <Work_Contact_Number>Work7864532890</Work_Contact_Number>
      <Home_Contact_Number>FirstEmp8013457896</Home_Contact_Number>
   </Worker>
   <Worker>
      <WorkerID>12568</WorkerID>
      <Work_Contact_Number>Work6782340167</Work_Contact_Number>
      <Home_Contact_Number>SecondEmp7853457896</Home_Contact_Number>
   </Worker>
</Workers>

请有人帮我弄清楚如何获得所需的输出?

标签: xsltxpathxslt-3.0

解决方案


问题是累加器匹配Employee_Batch_ID尝试使用电话的累加器值;但由于Employee_Batch_ID出现在Phone元素之前,Phone累加器值尚不可用。

我认为你必须颠倒逻辑:当你遇到 时Employee_Batch_ID/text(),将 ID 值保存为累加器 A 中的字符串;当您遇到 a 时Phone/text(),将 ID=phone 条目添加到 Accumulator B 中保存的地图中。


推荐阅读