Serhat
Serhat

Reputation: 658

XSLT Property name manipulation

I have an XML file that I would like to convert it to JSON with using XSLT. And I would like to manipulate property names of output JSON inside XSLT. But I could not manage to do that. Here is what I tried... I have following XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="xslt-trial.xsl"?>
<Invoice
  xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
  xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
  xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
  <cbc:AccountingCost>Cost Center</cbc:AccountingCost>
  <cbc:BuyerReference>Buyer reference</cbc:BuyerReference>
  <cac:InvoicePeriod>
    <cbc:StartDate>2020-02-11</cbc:StartDate>
    <cbc:EndDate>2020-02-21</cbc:EndDate>
  </cac:InvoicePeriod>
  <cac:ContractDocumentReference>
    <cbc:ID>Agreement Id</cbc:ID>
  </cac:ContractDocumentReference>
</Invoice>

and "xslt-trial.xsl" is:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

    <xsl:template match="/">{
        <xsl:apply-templates select="*"/>}
    </xsl:template>

    <!-- Object or Element Property-->
    <xsl:template match="*">
        "<xsl:value-of select="name()"/>" :<xsl:call-template name="Properties">
        <xsl:with-param name="parent" select="'Yes'"> </xsl:with-param>
    </xsl:call-template>
    </xsl:template>

    <!-- Array Element -->
    <xsl:template match="*" mode="ArrayElement">
        <xsl:call-template name="Properties"/>
    </xsl:template>

    <!-- Object Properties -->
    <xsl:template name="Properties">
        <xsl:param name="parent"></xsl:param>
        <xsl:variable name="childName" select="name(*[1])"/>
        <xsl:choose>
            <xsl:when test="not(*|@*)"><xsl:choose><xsl:when test="$parent='Yes'"> <xsl:text>&quot;</xsl:text><xsl:value-of select="."/><xsl:text>&quot;</xsl:text></xsl:when>
                <xsl:otherwise>"<xsl:value-of select="name()"/>":"<xsl:value-of  select="."/>"</xsl:otherwise>
            </xsl:choose>
            </xsl:when>
            <xsl:when test="count(*[name()=$childName]) > 1">{ "<xsl:value-of  select="$childName"/>" :[<xsl:apply-templates select="*" mode="ArrayElement"/>] }</xsl:when>
            <xsl:otherwise>{
                <xsl:apply-templates select="@*"/>
                <xsl:apply-templates select="*"/>
                }</xsl:otherwise>
        </xsl:choose>
        <xsl:if test="following-sibling::*">,</xsl:if>
    </xsl:template>

    <!-- Attribute Property -->
    <xsl:template match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
    </xsl:template>
</xsl:stylesheet>

I get this output from Edge browser:

{

        "Invoice" :{

        "cbc:AccountingCost" :"Cost Center",
        "cbc:BuyerReference" :"Buyer reference",
        "cac:InvoicePeriod" :{

        "cbc:StartDate" :"2020-02-11",
        "cbc:EndDate" :"2020-02-21"
                },
        "cac:ContractDocumentReference" :{

        "cbc:ID" :"Agreement Id"
                }
                }}

What I want to get is:

{

        "Invoice" :{

        "AccountingCost" :"Cost Center",
        "BuyerReference" :"Buyer reference",
        "InvoicePeriod" :{

        "StartDate" :"2020-02-11",
        "EndDate" :"2020-02-21"
                },
        "ContractDocumentReference" :{

        "ID" :"Agreement Id"
                }
                }}

As you can see, I would like to remove "cac:" and "cbc:" from property names. But I cannot manage to filter these values out.

Does anybody have a suggestion?

Upvotes: 0

Views: 174

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

If you use the function local-name() instead of the function name() then you should get element names without prefixes.

Upvotes: 1

Related Questions