1 Câu hỏi: Làm cách nào để khắc phục sự cố bản đồ XSLT 3.0?

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

Tôi đang lấy một tệp XML làm đầu vào chứa dữ liệu nhân viên và các giá trị ánh xạ, tức là Id gia đình công việc và Tên gia đình công việc. Vì vậy, khi một nhân viên có Id Gia đình công việc phù hợp thì chúng tôi sẽ thay thế tên Gia đình công việc trong Worker_Data và phần còn lại của các yếu tố trong Worker_Data là như nhau. Vì vậy, tôi đã sử dụng đối sánh Danh tính và sau đó gọi phần tử mà giá trị cần thay thế. Nhưng nó đang cho tôi khoảng trống cho tên Gia đình Công việc.

Tôi đã thử mã XSLT bên dưới để tạo bản đồ và được gọi tương tự cho đối sánh ID gia đình công việc. Nó chỉ là cho tôi trống không có gì khác. Không nhận được rõ ràng những gì tôi đang thiếu. Nếu bất kỳ ai trong số các bạn có thể cho tôi một gợi ý về những gì đang xảy ra sẽ thực sự hữu ích cho tôi.

<?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>

Đầu vào:

<?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>

Sản lượng dự kiến:

<?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 Câu trả lời                              1                         

Tôi chỉ cần sử dụng một khóa:

<?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>

Đối với yêu cầu của bạn về sử dụng phát trực tuyến và tích lũy, vì truyền phát chỉ hoạt động theo cách duy nhất để giải quyết đó là lưu trữ dữ liệu nhân viên có liên quan trong một chuỗi bản đồ và sau đó để thu thập dữ liệu chi tiết trong bản đồ như bạn đã cố sử dụng nó làm tham số trong mẫu cho từng mục trong chuỗi bản đồ dữ liệu công nhân xuất ra phần tử có liên quan:

<?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

Liệu điều đó có hoạt động tốt về mặt sử dụng bộ nhớ mà tôi chưa kiểm tra hay không.

    
1
2019-05-09 09: 14: 51Z
  1. Cảm ơn Martin, tôi muốn tạo mã này dưới dạng streamable. Đó là lý do tại sao tôi đến với khái niệm bản đồ trong XSLT3.0. Tôi đã tạo Streamable như không có trong đoạn trích trên, nhưng tôi sẽ bật khi tôi đặt mã trong ứng dụng. Xin lỗi đã làm bạn bối rối.
    2019-05-08 16: 11: 37Z
  2. > dữ liệu công nhân. Bạn sẽ cần xử lý đầu vào hai lần để lưu trữ các chi tiết sau lần xử lý đầu tiên và có sẵn trong quá trình xử lý dữ liệu công nhân thứ hai.
2019-05-08 16: 19: 55Z
  • Cảm ơn bạn đã giải thích Martin. Tôi vẫn đang học XSLT và thực sự không biết về quy trình làm việc Truyền phát này. Nếu bạn không phiền, bạn vui lòng gợi ý cho tôi một cuốn sách hoặc trang web để tìm hiểu và hiểu nội dung XSLT 3.0.
    2019-05-08 16: 26: 24Z
  • Chà, phần StackOverflow trên XSLT 3 stackoverflow.com/tags /xslt-3.0/info có rất nhiều liên kết đến thông số kỹ thuật và tài liệu, cũng như các phần trên XSLT nói chung và phiên bản XSLT 2 stackoverflow.com/tags/xslt-2.0/info chắc chắn cũng có ích nếu bạn chưa quen với XSLT nói chung. Tôi không chắc có cuốn sách nào dành riêng cho XSLT 3 nhưng Saxonica trong tài liệu của Saxon xử lý mọi thứ liên quan đến XSLT và XPath saxonica.com/html/documentation/USE-xsl/xslt30.html . Một nhà cung cấp khác, Altova, cũng có một phần dành riêng cho XPath 3 altova.com/training/xpath3 .
    2019-05-08 21: 05: 48Z
  • Cảm ơn bạn rất nhiều Martin. Điều này chắc chắn sẽ giúp tôi phân bổ.
    2019-05-08 21: 13: 15Z Bass
    JobFamilyDetails
  • nguồn đặt đây