0

sample.json:

{
"publishers": [
    {
        "sellers": {
            "books": [
                {
                    "test": {
                        "count": 1
                    },
                    "Name": "C",
                    "Type": "String"
                },
                {
                    "test": {
                        "count": 2
                    },
                    "Name": "C++",
                    "Type": "String"
                }
            ],
            "Author": "Michel"
        }
    },
    {
        "sellers": {
            "books": [
                {
                    "test": {
                        "count": 3
                    },
                    "Name": "Python",
                    "Type": "String"
                },
                {
                    "test": {
                        "count": 4
                    },
                    "Name": "Java",
                    "Type": "String"
                }
            ],
            "Author": "Robert"
        }
    }
]

}

sample.xslt:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="4.0"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="#all">
                                          
     <xsl:output method="json" indent="yes"/>
                                        
     <xsl:template match="." name="xsl:initial-template">
         <xsl:sequence select="array { ?publishers?* ! map { 'resourceType' : 'Asset',
                                                          'identifier' : map {'name' : array{?sellers?books?*?Name}} 
                                                        } }"/>
     </xsl:template> 
 </xsl:stylesheet>
                                    

I have applied the logic as I got replied in my previous question How to extract value from json object in xslt mapping. It's perfectly working for that requirement.

But as the json has been changed and I changed the logic little bit, then I got the error as SERE0023 JSON serialization: cannot handle a sequence of length 2 ("C", "C++"), then I have applied array just before getting the name of the books. This error got resolved after that. But I am unable to get the desired result.

I am getting below json as output, which doesn't meet the requirement

wrongOutput.json:

        [
        {
            "resourceType": "Asset",
            "indentifier": {
                "name": [
                    "C",
                    "C++"
                ]
            }
        },
        {
            "resourceType": "Asset",
            "indentifier": {
                "name": [
                    "Python",
                    "Java"
                ]
            }
        }
    ]
                                
    But expected output should be as below
                                
        **result.json**
     [
                                      {
                                        "resourceType": "Asset",
                                        "indentifier": { "name":"C" }
                                      },
                                      {
                                        "resourceType": "Asset",
                                        "indentifier": { "name":"C++" }
                                      },
                                      {
                                        "resourceType": "Asset",
                                        "indentifier": { "name":"Python" }
                                      },
                                      {
                                        "resourceType": "Asset",
                                        "indentifier": { "name":"Java" }
                                      }
                                    ]`
                                   
                                    

I have also tried with adding for-each loop as below, 'indentifier' : map {'name' : for-each{array{?seller?books?*?Name}}} But I am getting the error as XPST0003 Node constructor expressions are allowed only in XQuery, not in XPath

  • Can you please try to show the input JSON and XSLT without that indentation? Also, your JSON input has `sellers` and `seller`, is that right? Why does the output have the data from both although your XSLT selects only `sellers`? – Martin Honnen Aug 28 '23 at 19:40

1 Answers1

1

Presuming you have e.g.

{
  "publishers": [
      {
          "sellers": {
              "books": [
                  {
                      "test": {
                          "count": 1
                      },
                      "Name": "C",
                      "Type": "String"
                  },
                  {
                      "test": {
                          "count": 2
                      },
                      "Name": "C++",
                      "Type": "String"
                  }
              ]
          }
      },
      {    "sellers": {
              "books": [
                  {
                      "test": {
                          "count": 3
                      },
                      "Name": "Python",
                      "Type": "String"
                  },
                  {
                      "test": {
                          "count": 4
                      },
                      "Name": "Java",
                      "Type": "String"
                  }
              ]
          }
      }
  ]
}

you probably want XSLT alike

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all">
  
  <xsl:output method="json" indent="yes"/>

   <xsl:template match="." name="xsl:initial-template">
    <xsl:sequence 
      select="array { 
                ?publishers?*?sellers?books?* ! map {
                  'resourceType' : 'Asset',
                  'indentifier' : ?Name
                }
              }"/>
  </xsl:template> 
  
</xsl:stylesheet>

or perhaps for the inner identifier being itself a map/a JSON object

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all">
  
  <xsl:output method="json" indent="yes"/>

   <xsl:template match="." name="xsl:initial-template">
    <xsl:sequence 
      select="array { 
                ?publishers?*?sellers?books?* ! map {
                  'resourceType' : 'Asset',
                  'indentifier' : map { 'name': ?Name }
                }
              }"/>
  </xsl:template> 
  
</xsl:stylesheet>

For the changed input it would be rather

   <xsl:template match="." name="xsl:initial-template">
    <xsl:sequence 
      select="array { 
                ?publishers?*?seller?books?* ! map {
                  'resourceType' : 'Asset',
                  'indentifier' : map { 'name': ?Name }
                }
              }"/>
  </xsl:template>

but perhaps you want to insert another property in the output as well; ask a new question if you can't get it to work on your own.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • yes It's working fine as you have also replied earlier. But there is one more field which is inside sellers. I need to map that field also. Sorry I missed that field in my sample.json. I am modifying it. – Sujit Kumar Aug 28 '23 at 19:52
  • @SujitKumar: If the missing field truly presents a substantively new issue (which is doubtful), ask a new question. Otherwise, you should be able to adapt this answer to handle the missing field yourself. – kjhughes Aug 28 '23 at 19:57
  • @SujitKumar, perhaps better ask a new question, once an answer works against a code input sample posted it is rather not a good idea to change the input sample. And if the wanted output also changes and you can't adapt the concepts you should have learned from existing answers then ask a new question with both new input and output samples and how your attempt failed. – Martin Honnen Aug 28 '23 at 20:05