1

Is it possible to do a variable substitution for a value for an XML that is enclosed in a JSON object?

My setup is:

{
  "language": "en-US",
  "demoXml": "<General><Name>"ABC"</Name><Address>"123 abc"</Address><Language>en-US</Language></General>"
}

I want to do variable substitution for the Language key in the XML. Instead of hard-coding en-US in the XML, I want to substitute it for the Language variable. Is that possible?

kjhughes
  • 106,133
  • 27
  • 181
  • 240
hungryhippos
  • 617
  • 4
  • 15
  • Whart `Language` variable? XML is not a programming language, it doesn't have variables. – Barmar Feb 21 '23 at 18:53
  • Sorry, should've mentioned this is in JavaScript. – hungryhippos Feb 21 '23 at 18:56
  • The `javascript` tag does that, but I don't see how that's relevant. – Barmar Feb 21 '23 at 18:56
  • 1
    Are you talking about the `` tag in the XML? After you parse the XML with DOMDocument, you can use `xmldoc.getElementsByTagName('Languages')[0]` to get that tag, and assign its inner text. – Barmar Feb 21 '23 at 18:57

2 Answers2

1

At the JavaScript level, you could use a template literal:

const language = "en-US";
const msg = {
    "language": language,
    "demoXml": `<General>
                  <Name>ABC</Name>
                  <Address>123 abc</Address>
                  <Language>${language}</Language>
                </General>`
}

At the XML level, you could use an entity reference. See Can I use variables in XML files?

kjhughes
  • 106,133
  • 27
  • 181
  • 240
1

The JSON you've shown us isn't well formed: the quotes around "ABC" and "123 abc" need to be either omitted, or escaped as \".

If we ignore that problem, the following XSLT 3.0 transformation should do the job:

<xsl:transform version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="input-uri"/>
<xsl:variable name="json" select="json-doc($input-uri)"/>
<xsl:output method="json" indent="yes"/>

<xsl:template name="xsl:initial-template">
  <xsl:map>
     <xsl:map-entry key="'language'" select="$json?language"/>
     <xsl:map-entry key="'demoXml'">
       <xsl:variable name="final-xml">
         <xsl:apply-templates select="parse-xml($json?demoXml)"/>
       </xsl:variable>
       <xsl:sequence select="serialize($final-xml)"/>
     </xsl:map-entry>
  </xsl:map>
</xsl:template>

<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="Language">
  <Language><xsl:value-of select="$json?language"/></Language>
</xsl:template>

</xsl:transform>

(Not tested).

Michael Kay
  • 156,231
  • 11
  • 92
  • 164