Я пытаюсь получить одно поле, глядя на другое поле, используя XSLT Maps - PullRequest
0 голосов
/ 05 апреля 2019

Я пытаюсь использовать потоковую передачу (XSLT 3.0) для обработки вывода отчета из-за огромного объема. Я должен использовать XSLT из-за определенного формата вывода. При преобразовании вывода отчета мне нужно искать «Supplier_Invoice_number» на основе комбинации Customer_Invoice и Supplier, хранящейся в «Customer_Invoice_and_Supplier» на уровне строки. Мне нужно показать "Supplier_Invoice_number" на уровне строки.

Я создал XSLT-карты для хранения значений «Customer_Invoice_and_Supplier» и «Supplier_Invoice_number», чтобы при преобразовании строк я мог получить «Supplier_Invoice_number» для последующего отображения на уровне строк в выходных данных. Ниже приведен XSLT, который я создал, но я получаю пустое поле для "Supplier_Invoice_number". Я новичок в XSLT-картах и ​​потоковой передаче, поэтому буду очень признателен, если кто-нибудь поможет мне найти решение.

<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" xmlns:wd1="urn:com.workday.report/INT1109_CR_REV_Lookup_Supplier_Invoice_for_Customer_Invoice" xmlns:wd2="urn:com.workday.report/INT1109_CR_REV_Customer_Invoices_to_Connect" exclude-result-prefixes="xs" version="3.0">
<xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="SupplierInvoiceLookup CurrentLookupValue"/>
<xsl:output method="text"/>
<xsl:accumulator name="CurrentLookupValue" as="xs:string" initial-value="''" streamable="yes">
    <xsl:accumulator-rule match="wd1:Customer_Invoice_and_Supplier/text()" select="."/>
</xsl:accumulator>
<xsl:accumulator name="SupplierInvoiceLookup" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
    <xsl:accumulator-rule match="wd1:Supplier_Invoice_Number/text()" select="map:put($value, string(.), accumulator-before('CurrentLookupValue'))"/>
</xsl:accumulator>
<xsl:strip-space elements="*"/>
<xsl:template match="AggregatedData">
    <xsl:for-each select="wd2:Report_Data/wd2:Report_Entry/copy-of()">
        <xsl:text>{&#10;        "Company": "</xsl:text>
        <xsl:value-of select="wd2:Company"/>            
        <xsl:iterate select="wd2:lines">
            <xsl:text>      {&#10;</xsl:text>
            <xsl:text>        "sequence": "</xsl:text>
            <xsl:value-of select="wd2:sequence"/>
            <xsl:text>",&#10;</xsl:text>
            <xsl:text>        "sales_item_id": "</xsl:text>
            <xsl:value-of select="wd2:sales_item_id"/>
            <xsl:text>",&#10;</xsl:text>                
            <xsl:text>        "supplier_invoice_no": "</xsl:text>
            <xsl:variable name="supplier_invoice_no" select="accumulator-before('SupplierInvoiceLookup')( normalize-space( @wd2:Customer_Invoice_and_Supplier ) )"/>
            <xsl:value-of select="accumulator-before('SupplierInvoiceLookup')( normalize-space( @wd2:Customer_Invoice_and_Supplier ) )"/>
            <xsl:text>",&#10;</xsl:text>
        </xsl:iterate>            
    </xsl:for-each>
    <xsl:text>  &#10;</xsl:text>
</xsl:template>

Пример XML -

<?xml version="1.0" encoding="utf-8"?>
<AggregatedData>
    <wd:Report_Data xmlns:wd="urn:com.workday.report/INT1109_CR_REV_Lookup_Supplier_Invoice_for_Customer_Invoice">
        <wd:Report_Entry>
            <wd:Supplier_Invoice_Lines_group>
                <wd:Customer_Invoice_and_Supplier>INV-201900000024Dell Receivables LP</wd:Customer_Invoice_and_Supplier>
                <wd:Supplier_Invoice_Number>SI-00000047</wd:Supplier_Invoice_Number>
            </wd:Supplier_Invoice_Lines_group>
        </wd:Report_Entry>
        <wd:Report_Entry>
            <wd:Supplier_Invoice_Lines_group>
                <wd:Customer_Invoice_and_Supplier>INV-201900000024Charles Case [C]</wd:Customer_Invoice_and_Supplier>
                <wd:Supplier_Invoice_Number>SI-00000050</wd:Supplier_Invoice_Number>
            </wd:Supplier_Invoice_Lines_group>
        </wd:Report_Entry>
    </wd:Report_Data>
    <wd:Report_Data xmlns:wd="urn:com.workday.report/INT1109_CR_REV_Customer_Invoices_to_Connect">
        <wd:Report_Entry>
            <wd:Company>Financial/wd:Company>
            <wd:lines>
                <wd:sequence>a8</wd:sequence>
                <wd:sales_item_id>Data - Enterprise License</wd:sales_item_id>
                <wd:Customer_Invoice_and_Supplier>INV-201900000024Dell Receivables LP</wd:Customer_Invoice_and_Supplier>
            </wd:lines>
            <wd:lines>
                <wd:sequence>a9</wd:sequence>
                <wd:sales_item_id>TBA Trade Reports ATS Cncl</wd:sales_item_id>
                <wd:Customer_Invoice_and_Supplier>INV-201900000024Charles Case [C]</wd:Customer_Invoice_and_Supplier>
            </wd:lines>
        </wd:Report_Entry>
    </wd:Report_Data>
</AggregatedData>

1 Ответ

0 голосов
/ 06 апреля 2019

По какой-то причине вы использовали @wd2:Customer_Invoice_and_Supplier для выбора атрибута, хотя в вашем входе есть данные элемента, поэтому я думаю, что вы хотите

<xsl:template match="AggregatedData">
    <xsl:for-each select="wd2:Report_Data/wd2:Report_Entry/copy-of()">
        <xsl:text>{&#10;        "Company": "</xsl:text>
        <xsl:value-of select="wd2:Company"/>            
        <xsl:iterate select="wd2:lines">
            <xsl:text>      {&#10;</xsl:text>
            <xsl:text>        "sequence": "</xsl:text>
            <xsl:value-of select="wd2:sequence"/>
            <xsl:text>",&#10;</xsl:text>
            <xsl:text>        "sales_item_id": "</xsl:text>
            <xsl:value-of select="wd2:sales_item_id"/>
            <xsl:text>",&#10;</xsl:text>                
            <xsl:text>        "supplier_invoice_no": "</xsl:text>
            <xsl:value-of select="accumulator-before('SupplierInvoiceLookup')( normalize-space( wd2:Customer_Invoice_and_Supplier ) )"/>
            <xsl:text>",&#10;</xsl:text>
        </xsl:iterate>            
    </xsl:for-each>
    <xsl:text>  &#10;</xsl:text>
</xsl:template>

И я думаю, что вы хотите, чтобы карта была наоборот с точки зрения ключа и значений, чтобы аккумуляторы могли это сделать

<xsl:accumulator name="CurrentLookupValue" as="xs:string" initial-value="''" streamable="yes">
    <xsl:accumulator-rule match="wd1:Customer_Invoice_and_Supplier/text()" select="string()"/>
</xsl:accumulator>
<xsl:accumulator name="SupplierInvoiceLookup" as="map(xs:string,xs:string)" initial-value="map{}" streamable="yes">
    <xsl:accumulator-rule match="wd1:Supplier_Invoice_Number/text()" select="map:put($value, accumulator-before('CurrentLookupValue'), string(.))"/>
</xsl:accumulator>

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

Если вы хотите вывести JSON, обратите внимание, что XSLT 3 с XPath 3.1 отображает и обрабатывает массивы, а метод вывода json позволяет это сделать удобным способом, не пытаясь вывести пары скобок и имен элементов. Но это может быть лучше решено в отдельном вопросе, где вы покажете нам нужный JSON.

...