0
I have the belowjson as input
**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',
                          'indentifier' : map {'name' : array{?sellers?books?*?Name}},
                          'author' : map{'name' : ?sellers?Author}
                         
                        }
                      }"/>
          </xsl:template> 
          
        </xsl:stylesheet>

    
   

 I am getting the below output
    
   

 **output.json**
[
          {
            "resourceType": "Asset",
            "author": { "name":"Michel" },
            "indentifier": { "name":[ "C", "C++" ] }
          },
          {
            "resourceType": "Asset",
            "author": { "name":"Robert" },
            "indentifier": { "name":[ "Python", "Java" ] }
          }
        ]


But desired output is as bleow, 

**result.json**


[
              {
                "resourceType": "Asset",
                "author": { "name":Michel },
                "indentifier": { "name":"C" }
              },
              {
                "resourceType": "Asset",
                "author": { "name":Michel },
                "indentifier": { "name":"C++" }
              },
              {
                "resourceType": "Asset",
                "author": { "name":Robert },
                "indentifier": { "name":"Python" }
              },
              {
                "resourceType": "Asset",
                "author": { "name":Robert },
                "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**.

If I put select="array { publishers??sellers?books?} it is working fine to get the names of the book. But I am not getting the value of "author" in ouput.json as it's inside "sellers". So I tried with select="array {?publishers?*}, so that I can get the value of author. But I didn't get the desired output in "name" field.

1 Answers1

0

I think here it makes sense to use a for expression to bind a variable, you can do that in XPath 4 as

<xsl:template match="." name="xsl:initial-template">
    <xsl:sequence 
      select="array { 
                for $seller in ?publishers?*?sellers
                for $book in $seller?books?*
                return map {
                  'resourceType' : 'Asset',
                  'indentifier' : map {'name' : $book?Name },
                  'author' : map{'name' : $seller?Author}                
                }
              }"/>
</xsl:template> 

I think, for XPath 3.1 you need

<xsl:template match="." name="xsl:initial-template">
    <xsl:sequence 
      select="array { 
                for $seller in ?publishers?*?sellers
                return
                for $book in $seller?books?*
                return map {
                  'resourceType' : 'Asset',
                  'indentifier' : map {'name' : $book?Name },
                  'author' : map{'name' : $seller?Author}                
                }
              }"/>
</xsl:template> 
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110