0

I have the below json file

sample.json

{
    "books": [
        {
            "test": {
                "count": 1
            },
            "Name": "C",
            "Type": "String"
        },
        {
            "test": {
                "count": 2
            },
            "Name": "C++",
            "Type": "String"
        }
    ]
}

I have to extract the "Name" field value in xslt. If I am removing the test block, it's working fine. but with test block I am getting empty result.

I have tried with below xslt sample.xslt

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

  <xsl:function name="mf:apply-templates" as="item()*">
    <xsl:param name="items" as="item()*"/>
    <xsl:apply-templates select="$items"/>
  </xsl:function>

   <xsl:template match="." name="xsl:initial-template">
    <xsl:sequence select="array { mf:apply-templates(?books?*) }"/>
   
  </xsl:template> 
  
   
  
  <xsl:template match=".[. instance of map(xs:string, xs:anyAtomicType)]">
    <xsl:map>
        <xsl:map-entry key="'resourceType'" select="'Test'"/>
        
        <xsl:map-entry key="'identifier'">

                        <xsl:map>
                            <xsl:map-entry key="'name'"
                                select="?Name" />
                                </xsl:map>
                            </xsl:map-entry>
      
    </xsl:map>
  </xsl:template>
  
</xsl:stylesheet>

Desired Output should be as below:

output.json

[
  {
    "resourceType": "Test",
    "identifier": { "name":"C" }
  },
  {
    "resourceType": "Test",
    "identifier": { "name":"C++" }
  }
]
  • What is the wanted result, a sequence of name values? Some other JSON (then show the JSON you want to output)? – Martin Honnen Aug 26 '23 at 08:19
  • If you want just a sequence (e.g. `C, C++`) of `Name` values just use the XPath 3.1 lookup expression `?books?*?Name`, if you need a JSON array of Name values use e.g. `array { ?books?*?Name }`. – Martin Honnen Aug 26 '23 at 08:26
  • 1
    Consider to edit your question and show the desired output as a formatted code block. – Martin Honnen Aug 26 '23 at 08:36
  • If you have any flexibility in tooling then [Liquid](https://shopify.dev/docs/api/liquid) is a good option for JSON > JSON transforms. The template will be much simpler. There are a few implementations, including for [.Net](https://github.com/dotliquid/dotliquid) and [JS](https://liquidjs.com/index.html). – John Aug 26 '23 at 08:45

2 Answers2

0

We just need few adjustments here,

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

  <xsl:template match="/" name="xsl:initial-template">
    <xsl:sequence select="array { mf:apply-templates(json-doc('sample.json')?books?*) }"/>
  </xsl:template> 
  
  <xsl:template match=".[. instance of map(xs:string, xs:anyAtomicType)]">
    <xsl:map>
      <xsl:map-entry key="'resourceType'" select="'Test'"/>
      <xsl:map-entry key="'identifier'">
        <xsl:map>
          <xsl:map-entry key="'name'" select="string(?Name)" />
        </xsl:map>
      </xsl:map-entry>
    </xsl:map>
  </xsl:template>

</xsl:stylesheet>

Balaji Venkatraman
  • 1,228
  • 12
  • 19
0

You can use

<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 { 
                ?books?* ! map {
                  'resourceType' : 'Test',
                  'indentifier' : map { 'name' : ?Name }
                }
              }"/>
  </xsl:template> 
  
</xsl:stylesheet>
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110