1 Soalan: bagaimana untuk memperbaiki isu peta XSLT 3.0?

soalan dicipta di Wed, May 8, 2019 12:00 AM

Saya mengambil fail XML sebagai input yang mengandungi data pekerja dan nilai pemetaan i.e. Id Keluarga Kerja dan Nama Keluarga Pekerjaan. Oleh itu, apabila seorang pekerja mempunyai Id Keluarga Kerja padanan maka kami menggantikan nama Keluarga Kerja di Worker_Data dan seluruh elemen dalam Worker_Data adalah sama. Jadi saya menggunakan perlawanan Identity dan kemudian dipanggil elemen di mana nilai perlu diganti. Tetapi ia memberi saya kosong untuk nama Keluarga Pekerjaan.

Saya telah mencuba kod XSLT di bawah untuk membuat peta dan dipanggil sama untuk perlawanan ID Keluarga Kerja. Ia hanya memberi saya kosong apa-apa lagi. Tidak mendapat jelas apa yang saya hilang. Sekiranya ada di antara kamu yang boleh memberi saya petunjuk tentang apa yang salah, itu akan sangat membantu saya.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wd="urn:com.workday/bsvc" exclude-result-prefixes="xs" version="3.0">

    <xsl:mode streamable="no" on-no-match="shallow-skip" use- accumulators="JobFamilyLookup CurrentLookupValue" />

    <xsl:output method="xml" />

    <xsl:accumulator name="CurrentLookupValue" as="xs:string" initial- value="''" streamable="no">
        <xsl:accumulator-rule match="wd:JobFamilyID/text()" select="string()" />
    </xsl:accumulator>

    <xsl:accumulator name="JobFamilyLookup" as="map(xs:string,xs:string)" initial-value="map{}" streamable="no">
        <xsl:accumulator-rule match="wd:JobFamilyName/text()" select="map:put($value, accumulator- 
    before('CurrentLookupValue'),string(.))" />
    </xsl:accumulator>

    <xsl:strip-space elements="*" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="wd:Job_Family_ID">
        <xsl:copy>
            <xsl:value-of select="accumulator-before('JobFamilyLookup') ( 
        normalize-space( wd:Job_Family_ID ) )" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="wd:JobFamilyGroupDetails">

    </xsl:template>
</xsl:stylesheet>

Input:

<?xml version="1.0" encoding="UTF-8"?>
<wd:test xmlns:wd="urn:com.workday/bsvc">
<wd:Worker_Data>
    <wd:EmpID>50001</wd:EmpID>
    <wd:Job_Title>Global Talent Director</wd:Job_Title>
    <wd:Job_Family_ID>TAL_TALENT_ACQUISITION</wd:Job_Family_ID>
</wd:Worker_Data>
<wd:Worker_Data>
    <wd:EmpID>50000</wd:EmpID>
    <wd:Job_Title>Executive Assistant</wd:Job_Title>
    <wd:Job_Family_ID>ADMIN_EXECUTIVE_ASSISTANT</wd:Job_Family_ID>
</wd:Worker_Data>
<wd:JobFamilyGroupDetails>
    <wd:JobFamilyDetails>
        <wd:JobFamilyID>ADMIN_EXECUTIVE_ASSISTANT</wd:JobFamilyID>
        <wd:JobFamilyName>ADMIN - Executive Assistant</wd:JobFamilyName>
    </wd:JobFamilyDetails>
    <wd:JobFamilyDetails>
        <wd:JobFamilyID>TAL_TALENT_ACQUISITION</wd:JobFamilyID>
        <wd:JobFamilyName>TAL - Talent Acquisition</wd:JobFamilyName>
    </wd:JobFamilyDetails>
   </wd:JobFamilyGroupDetails>
</wd:test>

Keluaran yang dijangkakan:

<?xml version="1.0" encoding="UTF-8"?>
<wd:test xmlns:wd="urn:com.workday/bsvc">
<wd:Worker_Data>
    <wd:EmpID>50001</wd:EmpID>
    <wd:Job_Title>Global Talent Director</wd:Job_Title>
    <wd:Job_Family_ID>TAL - Talent Acquisition</wd:Job_Family_ID>
</wd:Worker_Data>
<wd:Worker_Data>
    <wd:EmpID>50000</wd:EmpID>
    <wd:Job_Title>Executive Assistant</wd:Job_Title>
    <wd:Job_Family_ID>ADMIN - Executive Assistant</wd:Job_Family_ID>
</wd:Worker_Data>
</wd:test>
    
0
1 Jawapan                              1                         

Saya hanya akan menggunakan kekunci:

<?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"
    xpath-default-namespace="urn:com.workday/bsvc"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

  <xsl:key name="details" match="JobFamilyDetails" use="JobFamilyID"/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="Worker_Data/Job_Family_ID[key('details', .)]">
      <xsl:copy>{key('details', .)/JobFamilyName}</xsl:copy>
  </xsl:template>

  <xsl:template match="JobFamilyGroupDetails"/>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/ncdD7mJ

Bagi permintaan anda menggunakan penstriman dan penumpuk, sebagai kerja penstriman meneruskan hanya satu-satunya cara untuk menyelesaikannya yang akan menyimpan data pekerja yang berkaitan dalam turutan peta dan kemudian untuk menangkap data terperinci dalam peta seperti yang anda cuba menggunakannya sebagai parameter dalam templat bagi setiap item dalam urutan peta data pekerja yang menghasilkan elemen yang berkaitan:

<?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:wd="urn:com.workday/bsvc"
    xpath-default-namespace="urn:com.workday/bsvc"
    exclude-result-prefixes="#all"
    version="3.0">

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

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

    <xsl:accumulator name="current-id" as="xs:string?" initial-value="()" streamable="yes">
        <xsl:accumulator-rule match="JobFamilyDetails/JobFamilyID/text()"
            select="string()"/>
    </xsl:accumulator>

    <xsl:accumulator name="details" as="map(xs:string, xs:string)" initial-value="map{}" streamable="yes">
        <xsl:accumulator-rule match="JobFamilyDetails/JobFamilyName/text()"
            select="map:put($value, accumulator-before('current-id'), string())"/>
    </xsl:accumulator>

    <xsl:accumulator name="workers" as="map(xs:string, xs:string)*" initial-value="()" streamable="yes">
        <xsl:accumulator-rule match="Worker_Data" select="$value, map { }"/>
        <xsl:accumulator-rule match="Worker_Data/EmpID/text()" 
            select="let $wmap := $value[last()]
            return ($value[position() lt last()], map:put($wmap, 'id', string()))"/>
        <xsl:accumulator-rule match="Worker_Data/Job_Title/text()" 
            select="let $wmap := $value[last()]
            return ($value[position() lt last()], map:put($wmap, 'title', string()))"/>
        <xsl:accumulator-rule match="Worker_Data/Job_Family_ID/text()" 
            select="let $wmap := $value[last()]
            return ($value[position() lt last()], map:put($wmap, 'jfid', string()))"/>
    </xsl:accumulator>

    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates/>
            <xsl:apply-templates select="accumulator-after('workers')" mode="output">
                <xsl:with-param name="details" select="accumulator-after('details')"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match=".[. instance of map(*)]" mode="output" expand-text="yes">
        <xsl:param name="details"/>
        <wd:Worker_Data>
            <wd:EmpID>{?id}</wd:EmpID>
            <wd:Job_Title>{?title}</wd:Job_Title>
            <wd:Job_Family_ID>{$details(?jfid)}</wd:Job_Family_ID>
        </wd:Worker_Data>      
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/pPzifpL/2

Sama ada yang berfungsi baik dari segi penggunaan memori yang saya tidak diuji.

    
1
2019-05-09 09: 14: 51Z
  1. Terima kasih Martin, saya ingin menjadikan kod ini sebagai streamabl. Itulah sebabnya saya datang untuk memetakan konsep dalam XSLT3.0. Saya membuat Streamable tidak ada dalam coretan di atas, tetapi saya akan menghidupkan apabila saya meletakkan kod dalam permohonan itu. Maaf untuk mengelirukan anda.
    2019-05-08 16: 11: 37Z
  2. Kerja-kerja penyiaran ke depan hanya supaya saya tidak melihat jalan, memandangkan struktur masukan anda di mana JobFamilyDetails disimpan selepas Worker_Data, untuk menggunakan streaming untuk mengakses butiran semasa memproses data pekerja. Anda perlu memproses input dua kali untuk menyimpan butiran selepas pemprosesan pertama dan memilikinya semasa pemprosesan kedua data pekerja.
    2019-05-08 16: 19: 55Z
  3. Terima kasih atas penjelasan Martin anda. Saya masih belajar XSLT dan benar-benar tidak menyedari prosedur kerja Streaming ini. Jika anda tidak keberatan, anda boleh cadangkan saya buku atau tapak untuk mengetahui dan memahami perkara XSLT 3.0.
    2019-05-08 16: 26: 24Z
  4. Nah, bahagian StackOverflow pada XSLT 3 stackoverflow.com/tags /xslt-3.0/info mempunyai banyak pautan ke spesifikasi dan bahan, seperti yang terdapat pada bahagian XSLT secara umum dan versi XSLT 2 stackoverflow.com/tags/xslt-2.0/info yang pasti juga membantu jika anda baru kepada XSLT secara umum. Saya tidak pasti terdapat sebarang buku yang didedikasikan untuk XSLT 3 tetapi Saxonica dalam dokumentasi Saxon merawat segala yang berkaitan dengan XSLT dan XPath saxonica.com/html/documentation/using-xsl/xslt30.html . Penjual lain, Altova, juga mempunyai bahagian yang diperuntukkan untuk XPath 3 altova.com/training/xpath3 .
    2019-05-08 21: 05: 48Z
  5. Terima kasih banyak Martin. Ini pasti akan membantu saya memperuntukkan.
    2019-05-08 21: 13: 15Z
sumber diletakkan di sini