0

I use XSLT to convert the XML to JSON. I use XSLT instead of Jackson/org.json as XSLT retains the namespace information.

For example, for the below SOAP XML request,

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <AccountDetailsRequest xmlns="http://com/blog/demo/webservices/accountservice">
      <accountNumber>12345</accountNumber>
    </AccountDetailsRequest>
  </soap:Body>
</soap:Envelope>

converts it to the following JSON.

{"soap:Envelope":{"soap:Body":{"AccountDetailsRequest":{"accountNumber":"12345"}}}}

The namespace definition is lost. But, I plan to store the namespace definition in a map.

I use Jackson/org.json[both return similar results] to convert it back to XML and I get the following XML:

<soap:Envelope>
<soap:Body>
<AccountDetailsRequest>
   <accountNumber>12345</accountNumber>
</AccountDetailsRequest>
</soap:Body>
</soap:Envelope>

The only part I am not able to figure out is the way to add the namespace definition assuming I can store that information in a map.

I considered adding a <root> </root> with all the namespaces in it, as W3C standard specifies it is a valid way to do so. But SOAP does not accept such XML.

Any way to get back the XML with proper namespace information?

user2761431
  • 925
  • 2
  • 11
  • 26
  • How about using the XML Dom setAttribute API? – aeberhart Aug 22 '20 at 05:04
  • If the namespace attribute has to be added on a certain element (not just the root element) you could use the path to the element as the map key. This question also contains several suggestions for this topic: https://stackoverflow.com/questions/4056419/how-would-i-express-xml-tag-attributes-in-json – aeberhart Aug 22 '20 at 05:17
  • Underscore-java library can convert xml to json and save all attributes. – Valentyn Kolesnikov Aug 26 '20 at 07:00

1 Answers1

0

When you say you're using XSLT to do the conversion, I guess that means you are doing it "by hand", rather than by using the XSLT 3.0 xml-to-json() function (which in fact wouldn't help you very much here).

But if your code has limitations, then it's hard to help you without seeing your code.

It's easy enough to find out all the namespaces in scope for an element by using the namespace axis, I'm not sure if you're trying that and getting it wrong, or if you're unaware of the feature. That's why we need to see your code.

It appears that the org.json converter accepts namespace declarations such as in:

String expectedStr = 
        "{\"addresses\":{\"address\":{\"name\":\"\",\"nocontent\":\"\","+
        "\"something\":[1, 2, 3]},\"xsi:noNamespaceSchemaLocation\":\"test.xsd\",\""+
        "xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"}}";

so you need to modify your XML-to-JSON converter to generate such declarations. The code you've adopted does

<xsl:apply-templates select="@*" mode="attr" />

at line 39 to process attributes. In XSLT 2.0+ you could process namespaces the same way using select="namespace::*". IIRC correctly however, XSLT 1.0 can't match namespace nodes in a pattern, so if you're stuck on 1.0 you would need to use something like

<xsl:for-each select="namespace::*">
  ...
</xsl:for-each>
Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • I use the XSLT from this link https://gist.github.com/zygimantus/73d79dd405fbb8345bebea2cb354b926. I use `TransformerFactory transform` function to do the XML to JSON conversion. I use org.json `XML.toString(json)` to convert it back to XML. The result is the XML without namespace definition. – user2761431 Aug 22 '20 at 17:32
  • Thanks for the update. I will give it a try. I am not stuck on XSLT 1.0. Is there a similar XSLT for 2.0? I could use it. – user2761431 Aug 26 '20 at 16:37