簡體   English   中英

XSLT 3 Saxon,使用深度更新和過濾器過濾不需要的數組元素

[英]XSLT 3 Saxon, filtering unwanted array elements using deep-update and filter

XSLT 3 is causing "SENR0001: Cannot serialize a map using this output method" error while transforming JSON natively using Saxon EE library capabilities ( 'saxon:with-pedigree', 'saxon:pedigree(.)?container, and 'deep-update ')。 在 XSLT 下方,將具有“可見性”屬性值的數組對象標識為“假”,然后從父數組 object 中排除選定對象。 跟蹤顯示預期值,但 Saxon Deep 更新操作邏輯失敗。 識別和數組過濾按預期工作,但將過濾后的數組分配給屬性沒有按預期工作,感謝您的輸入。

JSON 嵌入 XML

<list><![CDATA[
{
"customers":[
    {
        "customerType": "householdCustomer",
        "firstName": "Adam",
        "lastName": "L",
        "orders": [
            {
                "type": "smallOrder",
                "refUri": "orders/smallorder/xyz",
                "total": 125.0,
                "shippingAddUri": "/customer/123/address/89ui",
                "messages": [
                    {
                        "visibility": true,
                        "description": " your ordered delivered",
                        "id": "2345"
                    },
                    {
                        "visibility": false,
                        "description": "supplier challenge - covid supply chain issues",
                        "id": "2167"
                    },
                    {
                        "visibility": false,
                        "description": "order routed to correct procurement",
                        "id": "2049"
                    },
                    {
                        "visibility": false,
                        "description": "order gone to wrong procurement center",
                        "id": "2047"
                    },
                    {
                        "visibility": true,
                        "description": "order initiated",
                        "id": "2045"
                    }
                ]
            },
            {
                "type": "smallOrder",
                "refUri": "orders/smallorder/567z",
                "total": 135.0,
                "shippingAddUri": "/customer/678/address/90ny",
                "messages": [
                    {
                        "id": "23456",
                        "visibility": true,
                        "description": " your ordered delayed"
                    },
                    {
                        "id": "21677",
                        "visibility": false,
                        "description": "internal costcenter labor strike "
                    },
                    {
                        "id": "20459",
                        "visibility": true,
                        "description": "order initiated"
                    }
                ]
            }
        ]
    },
    {
        "customerType": "householdCustomer",
        "firstName": "Thomas",
        "lastName": "N",
        "orders": [
            {
                "type": "smallOrder",
                "refUri": "orders/smallorder/xyz",
                "total": 125.0,
                "shippingAddUri": "/customer/123/address/89ui",
                "messages": [
                    {
                        "id": "2345",
                        "visibility": true,
                        "description": " your ordered delivered"
                    },
                    {
                        "id": "2167",
                        "visibility": false,
                        "description": "supplier challenge - covid supply chain issues"
                    },
                    {
                        "id": "2045",
                        "visibility": false,
                        "description": "order initiated"
                    }
                ]
            },
            {
                "type": "smallOrder",
                "refUri": "orders/smallorder/xr7z",
                "total": 234.0,
                "shippingAddUri": "/customer/uio/address/34bnmy",
                "messages": [
                    {
                        "id": "90",
                        "visibility": true,
                        "description": " your ordered delayed"
                    },
                    {
                        "id": "67",
                        "visibility": false,
                        "description": "Postal delays, finding alternative route "
                    },
                    {
                        "id": "34",
                        "visibility": true,
                        "description": "order initiated"
                    }
                ]
            }
        ]
    },
    {
        "customerType": "corporateCustomer",
        "corpName": "Telsoft Inc",
        "orders": [
            {},
            {}
        ]
    },
    {
        "customerType": "corporateCustomer",
        "corpName": "Orange Inc",
        "orders": [
            {},
            {}
        ]
    },
    {
        "customerType": "corporateCustomer",
        "corpName": "Notebook Inc",
        "orders": [
            {},
            {}
        ]
    }
]
}
]]>
</list>

XSLT 原生轉換 JSON。

<?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:fn="http://www.w3.org/2005/xpath-functions" xmlns:saxon="http://saxon.sf.net/" xmlns:math="http://www.w3.org/2005/xpath-functions/math" xmlns:array="http://www.w3.org/2005/xpath-functions/array" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:err="http://www.w3.org/2005/xqt-errors" xmlns:f="http://example.com/f" extension-element-prefixes="saxon" exclude-result-prefixes="array fn map math xhtml xs err saxon" version="3.0">

    <xsl:output method="text" omit-xml-declaration="yes" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="list" name="xsl:initial-template">
    
        <!-- read json from XML -->
        <xsl:variable name="data" as="map(*)"  select="parse-json(.)"/>
    
        <!-- identify household customers -->
        <xsl:variable name="householdCustomers" as="array(*)">
        <saxon:array    select="$data?customers?*[?customerType='householdCustomer']"/>
        </xsl:variable>
        
        
        <!-- produce hhsWithPedigree refrence structure using WithPedigree -->
        <xsl:variable name="hhsWithPedigree" as="array(*)">
        <saxon:array    select="$householdCustomers => saxon:with-pedigree()"/>
        </xsl:variable> 
        
        <!-- identify all objects with visibility as false' -->
        <xsl:variable name="visibilityArrayWithFalse" as="array(*)">
        <saxon:array    select="saxon:map-search($hhsWithPedigree, 'visibility', function($v){ fn:matches(
                    xs:string($v), 'false') })"/>
        </xsl:variable> 
        
        <!-- iterate through objects with 'visibility' attribute value as 'false' then identify root array
        and exclude the selected objects -->
        <xsl:for-each select="$visibilityArrayWithFalse?*?map">
            <xsl:variable name="visiOne" select="saxon:pedigree(.)?container"/>
            <saxon:deep-update
                 root = "$visiOne"
                select = "."
                action = " let  $filteredValues := array:filter(., function($v) {map:get($v,'visibility') eq true() }), $noOfValues := count($filteredValues), $trace := trace($filteredValues, 'I m tracing') return $filteredValues "/>
        </xsl:for-each>
        
                
        <xsl:value-of select=" $householdCustomers => serialize(map { 'method' : 'json', 'use-character-maps' : map { '/' : '/' } })"/>
    

    </xsl:template>

</xsl:stylesheet>

錯誤詳情:

Error in saxon:deep-update/@root on line 31 column 222 of question-v1.xslt:
  SENR0001: Cannot serialize a map using this output method
     Focus
        Context item: map{"visibility":false(), "description":"supplier challenge - covid supply c...", "id":"2167", }
        Context position: 1
     Local variables
        $vv:v0 = coerced anon:f_1766145591
        $householdCustomers = [map{"firstName":"Adam", "lastName":"L", "customerType":"householdCustomer",  ...}, map{"firstName":"Thomas", "lastName":"N", "customerType":"householdCustomer",  ...}, ]
     invoked by unknown caller (class net.sf.saxon.expr.instruct.ForEach) at file:/C:/apps/xslt3/question-v1.xslt#26
  In template rule with match="list" on line 6 of question-v1.xslt
     Focus
        Context item: /list
        Context position: 1
     Local variables
        $vv:v0 = coerced anon:f_1766145591
        $householdCustomers = [map{"firstName":"Adam", "lastName":"L", "customerType":"householdCustomer",  ...}, map{"firstName":"Thomas", "lastName":"N", "customerType":"householdCustomer",  ...}, ]
     invoked by built-in template rule (text-only)
Cannot serialize a map using this output method

我認為部分錯誤是您使用saxon:deep-update而不將其結果存儲在可以采用 XDM map 或數組的變量中,該指令返回/輸出諸如 map 或xsl:for-each內的數組並且 output 方法是text ,您會收到錯誤,因為saxon:deep-update返回的結果的序列化無法使用該方法text進行序列化。

我不太確定您想要實現什么,但我想您不想 output 的結果saxon:deep-update ,您只希望它對您的地圖產生副作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM