XSL Policy is not respecting XML attributes

Not applicable

Hi all,

I have a problem with XSL policy. This policy is default created when i create WSL proxy and this add the namespace in the payload. The name space is correct an other nodes but when one node has attributes this policy convert attributes in other node.

This is XSL policy.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://schema.com.poc" version="1.0">
<xsl:output encoding="utf-8" indent="yes" method="xml" omit-xml-declaration="yes"/>
<!-- Stylesheet to inject namespaces into a document in specific places -->
<xsl:template match="/">
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<xsl:choose>
<!-- Handle 'Root' wrapper added by JSON to XML policy -->
<xsl:when test="normalize-space(/Root)">
<sch:pocSync>
<xsl:apply-templates select="node()|@*"/>
</sch:pocSync>
</xsl:when>
<!-- Handle 'Array' wrapper added by JSON to XML policy -->
<xsl:when test="normalize-space(/Array)">
<sch:pocSync>
<xsl:apply-templates select="node()|@*"/>
</sch:pocSync>
</xsl:when>
<!-- If the root element is not what was in the schema, add it -->
<xsl:when test="not(normalize-space(/pocSync))">
<sch:pocSync>
<xsl:apply-templates select="node()|@*"/>
</sch:pocSync>
</xsl:when>
<!-- everything checks out,  just copy the xml-->
<xsl:otherwise>
<xsl:apply-templates select="node()|@*"/>
</xsl:otherwise>
</xsl:choose>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
<xsl:template match="/Root/*" name="copy-root">
<xsl:element name="sch:{local-name()}">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>

<xsl:template match="/Array/*" name="copy-array">
<xsl:element name="sch:{local-name()}">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>

<xsl:template match="*[not(local-name()='Root') and not(local-name()='Array')]" name="copy-all">
<xsl:element name="{local-name()}">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<!-- template to copy the rest of the nodes -->
<xsl:template match="comment() | processing-instruction()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>

Thanks.

Regards.

0 4 336
4 REPLIES 4

not clear.

Can you give a specific example of

  • input you provided to this XSL
  • output you expected to see
  • output you actually observed

?

Hi Dino ♦♦

This is my WSL proxy and my input for XSL is the transform JSON to XML

my json is this:

{
"id": "1",
"ext": "TM",
"amount" : {
        "#attrs" : {
            "#attCode" : "MNX"
        },       
        "#text" : "10"
 }  
 }

The transform to XML is correct

6386-a1.png

In this part the paylod is correct but yet add name spaces.

In the next policy add name space with XML policy.

6387-a2.png

When execute XSL policy the node "amount" change and i need that those node dont change. only pass with nodes with attributes.

"Ouput i see"

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://schema.com.poc">
<soapenv:Header/>
<soapenv:Body>
<sch:pocSync>

<id>1</id>
<ext>TMX</ext>
<amount>MX10</amount>

</sch:pocSync>
</soapenv:Body>
</soapenv:Envelope>

"Ouput i want see"

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://schema.com.poc">
<soapenv:Header/>
<soapenv:Body>
<sch:pocSync>

<id>1</id>
<ext>TMX</ext>
<amount currencyCode="MX">10</amount>

</sch:pocSync>
</soapenv:Body>
</soapenv:Envelope

Its is corect

<amount currencyCode="MNX">20.0</amount>

Its is wrong

<amount>MX10.0</amount> 

Thanks

Hi Josh

I think your XSL is a little off. There is no statement to copy the attribute you want.

This is independent of Apigee Edge. You just need to get the XSL to do the thing you want. I tried with this XSL :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:sch="http://schema.com.poc"
    exclude-result-prefixes="sch"
    version="1.0">


  <xsl:output encoding="utf-8"
              indent="yes"
              method="xml"
              omit-xml-declaration="yes"/>


  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:copy-of select="namespace::*"/>
      <xsl:apply-templates select="node()"/>
    </xsl:element>
  </xsl:template>


  <!-- Stylesheet to inject namespaces into a document in specific places -->
  <xsl:template match="/">
    <soapenv:Envelope>
      <soapenv:Header/>
      <soapenv:Body>
        <xsl:apply-templates select="node()|*"/>
      </soapenv:Body>
    </soapenv:Envelope>
  </xsl:template>


  <xsl:template match="/*" name="copy-root">
    <pocSync namespace="http://schema.com.poc">
      <xsl:apply-templates select="node()|*"/>
    </pocSync>
  </xsl:template>


  <xsl:template match="/*[name() = 'Root' or name() = 'Array']/*" name="copy-root-child">
    <xsl:element name="{local-name()}" >
      <!-- <xsl:copy-of select="namespace::*"/> -->
      <xsl:copy-of select="@*"/> <!-- copy all attributes to the new element -->
      <xsl:apply-templates select="node()"/>
    </xsl:element>
  </xsl:template>


  <!-- template to copy the rest of the nodes -->
  <xsl:template match="comment() | processing-instruction()">
    <xsl:copy/>
  </xsl:template>


</xsl:stylesheet>


...and got this output XML:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <pocSync namespace="http://schema.com.poc">
         <id>1</id>
         <ext>TM</ext>
         <amount attCode="MNX">10</amount>
      </pocSync>
   </soapenv:Body>
</soapenv:Envelope>

...which is I think about what you wanted. You said you wanted "currencyCode" but the inbound XML had "attCode" ... not sure about how you planned to map that.

But this updated XSL ought to help you a little.

Hi Dino,

I have the same problem with you XSL. =(

now my XML ouput is

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <pocSync namespace="http://schema.com.poc">
         <id>1</id>
         <ext>TM</ext>
         <amount>10</amount>
      </pocSync>
   </soapenv:Body>
</soapenv:Envelope>

And my payload is

{
    "id": "1",
    "ext": "TM",
    "amount" : {
                 "#attrs" : {
                 "@Code" : "MNX"
        	},       
        	"#text" : "10"
 		}  
 }

This is my policy Json to XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<JSONToXML async="false" continueOnError="false" enabled="true" name="poc-json-to-xml">
    <DisplayName>payService JSON TO XML</DisplayName>
    <Properties/>
    <Options>
        <NullValue>NULL</NullValue>
        <NamespaceBlockName>@xmlns</NamespaceBlockName>
        <DefaultNamespaceNodeName>{replace7}lt;/DefaultNamespaceNodeName>
        <NamespaceSeparator>:</NamespaceSeparator>
        <TextNodeName>#text</TextNodeName>
        <AttributePrefix>@</AttributePrefix>
        <AttributeBlockName>#attrs</AttributeBlockName>
        <InvalidCharsReplacement>_</InvalidCharsReplacement>
        <!--  <ObjectRootElementName>Root</ObjectRootElementName> 
        <ArrayRootElementName>Array</ArrayRootElementName> -->
        <ArrayItemElementName>Item</ArrayItemElementName>
    </Options>
    <OutputVariable>request</OutputVariable>
    <Source>request</Source>
</JSONToXML>

Thanks