How can I convert *.RESX XML file to JSON file in C#?
I have regular RESX file. For example:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data xml:space="preserve" name="KEY_1">
<value>Text A</value>
</data>
<data xml:space="preserve" name="KEY_2">
<value>Text B</value>
</data>
</root>
I need to convert this file to JSON file:
{
"Texts": [
{
"id": "KEY_1",
"text": "Text A"
},
{
"id": "KEY_2",
"text": "Text B"
}
]
}
As you can see for conversion is relevant only part with data:
<data xml:space="preserve" name="KEY_1">
<value>Text A</value>
</data>
<data xml:space="preserve" name="KEY_2">
<value>Text B</value>
</data>
Everything else is irrelevant for transformation.
Name in data attribute XML => is id in JSON file.
Value in XML=> is text in JSON file.
EDIT:
I have solution, but I think that it can be done better
using System.Xml;
using System.IO;
using System.Collections.Generic;
using System.Linq;
namespace XMLtoJSON
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, string> result = new Dictionary<string, string>();
// To convert an XML node contained in string xml into a JSON string
var xml = File.ReadAllText(#"C:\Test\ClientLocalization.en-US.resx");
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeList node = doc.GetElementsByTagName("data");
foreach (XmlNode item in node)
{
var value = item.InnerText.Trim();
var keyName = item.Attributes.Cast<XmlAttribute>().FirstOrDefault(f => f.Name == "name");
if (keyName != null)
{
var key = keyName.InnerText.Trim();
result.Add(key, value);
}
}
string res = #"{ ""Text"" : [ ";
foreach (var item in result)
{
res += "{";
res += $" \"id\":\"{item.Key}\",\"text\":\"{item.Value}\"";
res += "},";
}
res = res.Remove(res.Length - 1);
res += #" ]} ";
}
}
}
Instead of using XmlDocument, I would use XElement as it is much more LINQ-friendly. Use XElement.Parse to load the XML, then select the nodes you are interested in and shape them into an anonymous object structure that mirrors the JSON you want. Finally, use your favorite JSON serializer (such as Json.Net or JavaScriptSerializer) to create the JSON from there. I don't recommend hand-rolling your own JSON, as it is very error prone.
using Newtonsoft.Json;
var xml = File.ReadAllText(#"C:\Test\ClientLocalization.en-US.resx");
var obj = new
{
Texts = XElement.Parse(xml)
.Elements("data")
.Select(el => new
{
id = el.Attribute("name").Value,
text = el.Element("value").Value.Trim()
})
.ToList()
};
string json = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);
// OR:
//JavaScriptSerializer jss = new JavaScriptSerializer();
//string json = jss.Serialize(obj);
Console.WriteLine(json);
Fiddle: https://dotnetfiddle.net/ZIaCjd
I'd recommend you the JSON.NET Framework.
It has built-in functions for converting XML to JSON and vice versa.
Example:
string xml = #"<?xml version='1.0' standalone='no'?>
<root>
<person id='1'>
<name>Alan</name>
<url>http://www.google.com</url>
</person>
<person id='2'>
<name>Louis</name>
<url>http://www.yahoo.com</url>
</person>
</root>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
//{
// "?xml": {
// "#version": "1.0",
// "#standalone": "no"
// },
// "root": {
// "person": [
// {
// "#id": "1",
// "name": "Alan",
// "url": "http://www.google.com"
// },
// {
// "#id": "2",
// "name": "Louis",
// "url": "http://www.yahoo.com"
// }
// ]
// }
//}
Related
I am facing some issue while extracting XML value from the JSON element using XSLT in OIC, the requirement is to map those XML value to the XML element at target side by applying loop as xml value element is repeating. below are the input and output format, require your expert input-
input
{
"requestMessage":{
"contactName":"",
"primaryPhoneExt":"",
"secondaryPhoneExt":"",
"thirtyMinCallReqFlg":"<cmPCReadingDetails><readingDetailsList><readSequence>1</readSequence><readingUOM>1</readingUOM><readingTOU>1</readingTOU><readingSQI>1</readingSQI><meterRegisterTypeCode>KW</meterRegisterTypeCode><numberOfDials>6</numberOfDials><numberOfDecimals>3</numberOfDecimals><upperLimit>0</upperLimit><lowerLimit>41</lowerLimit><reading>41</reading><newReading>40</newReading><override>false</override><measurementCondition>501000</measurementCondition><measurementDescription>Regular</measurementDescription></readingDetailsList><readingDetailsList><readSequence>2</readSequence><readingUOM>1</readingUOM><readingTOU>1</readingTOU><readingSQI>1</readingSQI><meterRegisterTypeCode>KWH</meterRegisterTypeCode><numberOfDials>5</numberOfDials><numberOfDecimals>0</numberOfDecimals><upperLimit>0</upperLimit><lowerLimit>312</lowerLimit><reading>312</reading><newReading>111</newReading><override>false</override><measurementCondition>501000</measurementCondition><measurementDescription>Regular</measurementDescription></readingDetailsList></cmPCReadingDetails> ",
"contactPersonPhone":""
}
}
Target Element-:
<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.org"
targetNamespace="http://www.example.org" elementFormDefault="qualified">
<xsd:element name="thirtyMinCallReqFlg">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="cmPCReadingDetails">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="readingDetailsList" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="readSequence" type="xsd:integer"/>
<xsd:element name="readingUOM" type="xsd:integer"/>
<xsd:element name="readingTOU" type="xsd:integer"/>
<xsd:element name="readingSQI" type="xsd:integer"/>
<xsd:element name="meterRegisterTypeCode" type="xsd:string"/>
<xsd:element name="numberOfDials" type="xsd:integer"/>
<xsd:element name="numberOfDecimals" type="xsd:integer"/>
<xsd:element name="upperLimit" type="xsd:integer"/>
<xsd:element name="lowerLimit" type="xsd:integer"/>
<xsd:element name="reading" type="xsd:integer"/>
<xsd:element name="newReading" type="xsd:integer"/>
<xsd:element name="override" type="xsd:string"/>
<xsd:element name="measurementCondition" type="xsd:integer"/>
<xsd:element name="measurementDescription" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
appreciate your help.
Regards,
Nilesh Jha
This is my NLog configuration:
<layout type="JsonLayout">
<attribute name="businessProcessName" layout="${event-properties:rawMessage:item=BusinessProcess}" />
<attribute name="businessDepartmentName" layout="${event-properties:rawMessage:item=BusinessDepartment}" />
<attribute name="logType" layout="${event-properties:rawMessage:item=logType}" />
<attribute name="queueName" layout="${event-properties:rawMessage:item=QueueName}" />
<attribute name="data" layout="${event-properties:rawMessage:item=LogF_AllTransactionData}" />
</layout>
Which is giving me the following result:
{ "businessProcessName": "ACME", "businessDepartmentName": "Lior", "logType": "User", "queueName": "LoggingTest", "data": "{\r\n \"ExecuterJobGUID\": \"Studio_05fe3a0e-dc3b-4635-a521-5fe450cdb13e\",\r\n \"LogF_TransactionReference\": \"MyTransaction\",\r\n \"LogF_StartTransactionTime\": \"08\/02\/2022 17:11:33\",\r\n \"LogF_TransactionId\": \"23031\",\r\n \"LogF_QueueName\": \"LoggingTest\",\r\n \"LogF_QueueDefinitionId\": 545,\r\n \"LogF_SpecificContent\": {\r\n \"FirstName\": \"Lior\",\r\n \"LastName\": \"Hen\",\r\n \"BirthDate\": \"1989-12-03T00:00:00Z\"\r\n },\r\n \"LogF_Progress\": \"\",\r\n \"LogF_RetryNo\": 0,\r\n \"Gender\": \"Male\",\r\n \"City\": \"Ashdod\"\r\n}" }
I have two questions please:
How can I bring 'data' as Json and not as string?
How can I bring a single key from 'data', such as 'LogF_TransactionReference'?
Thank you!
If you know that the LogEvent-Property contains valid JSON, then you can specify encode="false":
<attribute name="data" layout="${event-properties:item=LogF_AllTransactionData}" encode="false" />
Then NLog will not encode/escape the LogEvent-Property-Value as JSON-string-property.
NLog ${event-properties} has the objectpath-option, but it requires that you provide the original object, instead of having serialized to JSON upfront.
<attribute name="data_id" layout="${event-properties:item=LogF_AllTransactionData:objectpath=Id}" />
<attribute name="data" layout="${event-properties:item=LogF_AllTransactionData:format=#}" encode="false" />
Alternative approach would be to implement custom-layout-renderer that parses the JSON-Object and output the wanted property. But it has a performance penalty.
See also: https://github.com/NLog/NLog/wiki/How-to-use-structured-logging
I am currently using ODI to import data that is in JSON format into an Oracle Database. I am currently using the Complex File topology, which requires me to identify the JSON file and the XSD used to translate it to XML before it maps the data into a table in the database.
I have a JSON file called sample.json:
{"DATA_DS": {"G_1": [
{
"FIELDA": "Test Data ",
"FIELDB": "12345",
"FIELDC": " ",
"FIELDD": null,
"FIELDE": " Test Data"
}
]}}
I have an XSD called sample.xsd:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://TargetNamespace.com/InboundService" xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd" targetNamespace="http://TargetNamespace.com/InboundService" elementFormDefault="qualified" nxsd:version="JSON" nxsd:encoding="UTF-8">
<xsd:element name="Root-Element">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="DATA_DS">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="G_1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="FIELDA" type="xsd:string"/>
<xsd:element name="FIELDB" type="xsd:string"/>
<xsd:element name="FIELDC" type="xsd:string"/>
<xsd:element name="FIELDD" type="xsd:string"/>
<xsd:element name="FIELDE" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
When trying to translate from JSON to XML, it says that it cannot normalize.
On further investigation, I noticed that the error occurs due to FIELDC having ONLY space.
I want to be able to keep everything that is inside the double quotes, including space.
I have tried changing the XSD twice, but to no avail.
Created a simpleType and changed the type of every element inside to use the new simpleType:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://TargetNamespace.com/InboundService" xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd" targetNamespace="http://TargetNamespace.com/InboundService" elementFormDefault="qualified" nxsd:version="JSON" nxsd:encoding="UTF-8">
<xsd:element name="Root-Element">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="DATA_DS">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="G_1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="FIELDA" type="stringspace"/>
<xsd:element name="FIELDB" type="stringspace"/>
<xsd:element name="FIELDC" type="stringspace"/>
<xsd:element name="FIELDD" type="stringspace"/>
<xsd:element name="FIELDE" type="stringspace"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="stringspace">
<xsd:restriction base="xsd:string">
<xsd:whiteSpace value="preserve" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
Created a simpleType inside each element and identify to preserve whitespace:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://TargetNamespace.com/InboundService" xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd" targetNamespace="http://TargetNamespace.com/InboundService" elementFormDefault="qualified" nxsd:version="JSON" nxsd:encoding="UTF-8">
<xsd:element name="Root-Element">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="DATA_DS">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="G_1" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="FIELDA"><xsd:simpleType><xsd:restriction base="xsd:string"><xsd:whiteSpace value="preserve"/></xsd:restriction></xsd:simpleType></xsd:element>
<xsd:element name="FIELDB"><xsd:simpleType><xsd:restriction base="xsd:string"><xsd:whiteSpace value="preserve"/></xsd:restriction></xsd:simpleType></xsd:element>
<xsd:element name="FIELDC"><xsd:simpleType><xsd:restriction base="xsd:string"><xsd:whiteSpace value="preserve"/></xsd:restriction></xsd:simpleType></xsd:element>
<xsd:element name="FIELDD"><xsd:simpleType><xsd:restriction base="xsd:string"><xsd:whiteSpace value="preserve"/></xsd:restriction></xsd:simpleType></xsd:element>
<xsd:element name="FIELDE"><xsd:simpleType><xsd:restriction base="xsd:string"><xsd:whiteSpace value="preserve"/></xsd:restriction></xsd:simpleType></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
I am kind of new to the whole JSON,XML,XSD space, so any kind of help will be greatly appreciated.
Thanks a lot in advance! :)
You say "it says that it cannot normalize" but you don't say what "it" is.
There are many ways of converting to JSON to XML, and you haven't said which one you are using. It sounds to me as if "it" is the particular conversion tool or library that you are using, and your problem is with this tool or library.
Also, rather than paraphrasing an error message, it's best to quote it exactly. There may be people here who recognize it and can tell you exactly what it means.
I'm using BIML to create a ScriptComponenteSource, with a ScriptComponentProject.
The project contains the following (which is taken from the Varigence samples)
<ScriptProjects>
<ScriptComponentProject Name="SC_AD-Accounts" TargetFrameworkVersion="NetFX461">
<AssemblyReferences>
<AssemblyReference AssemblyPath="System" />
<AssemblyReference AssemblyPath="System.Data" />
<AssemblyReference AssemblyPath="System.Windows.Forms" />
<AssemblyReference AssemblyPath="System.Xml" />
<AssemblyReference AssemblyPath="Microsoft.SqlServer.TxScript" />
<AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSRuntimeWrap" />
<AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSPipelineWrap" />
<AssemblyReference AssemblyPath="Microsoft.SqlServer.PipelineHost" />
<AssemblyReference AssemblyPath="System.DirectoryServices" />
</AssemblyReferences>
<OutputBuffers>
<OutputBuffer Name="Output0">
<Columns>
<Column Name="UUId" DataType="String" Length="255" />
<Column Name="Surname" DataType="String" Length="255" />
<Column Name="GivenName" DataType="String" Length="255" />
<Column Name="EmailAddress" DataType="String" Length="255" />
<Column Name="UPN" DataType="String" Length="255" />
</Columns>
</OutputBuffer>
</OutputBuffers>
<Files>
<File Path="main.cs"><![CDATA[
using System;
using System.Data;
using System.DirectoryServices;
using Microsoft.SqlServer.Dts.Pipeline;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public partial class ScriptMain : UserComponent
{
public override void CreateNewOutputRows()
{
/*
Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
*/
var searchBaseNames = new [] {
"OU=UserP,OU=User,DC=MyDC",
"OU=UserPS,OU=User,DC=MyDC",
"OU=UserPSC,OU=User,DC=MyDC"
};
var propertiesToLoad = new [] {
"sn",
"givenName",
"mail",
"userPrincipalName",
"objectGuid",
"serialNumber"
};
foreach (var searchBaseName in searchBaseNames) {
var searchBaseEntry = new DirectoryEntry("LDAP://" + searchBaseName);
var directorySearcher = new DirectorySearcher(searchBaseEntry, "(objectClass=user)", propertiesToLoad, SearchScope.Subtree) {
PageSize = 2500
};
foreach (SearchResult searchResult in directorySearcher.FindAll()) {
var surname = searchResult.Properties["sn"][0] as string;
var givenName = searchResult.Properties["givenName"][0] as string;
var email = searchResult.Properties["mail"][0] as string;
var upn = searchResult.Properties["userPrincipalName"][0] as string;
string uuid = null;
if(searchResult.Properties.Contains("serialNumber"))
{
uuid = searchResult.Properties["serialNumber"][0] as string;
if(!string.IsNullOrEmpty(uuid))
uuid = uuid;
}
if(string.IsNullOrEmpty(uuid))
{
var objectGuidBytes = searchResult.Properties["objectGuid"][0] as byte[];
var objectGuid = new Guid(objectGuidBytes);
uuid = objectGuid.ToString();
}
if(string.IsNullOrEmpty(surname) || string.IsNullOrEmpty(givenName) ||
string.IsNullOrEmpty(upn) || string.IsNullOrEmpty(email))
{
continue;
}
Output0Buffer.AddRow();
Output0Buffer.Surname = surname;
Output0Buffer.GivenName = givenName;
Output0Buffer.UPN = upn;
Output0Buffer.EmailAddress = email;
}
}
}
}
]]></File>
</Files>
</ScriptComponentProject>
</ScriptProjects>
This will not compile, due to the BIML-expansion not knowing about Output0Buffer and the overriden method (they will be created automatically).
Is there a way to resolve this hen-egg-problem?
I blogged about it,
https://billfellows.blogspot.com/2015/10/biml-script-component-source.html
You need to specify the IsSynchronous property as false for the output buffer. Otherwise, it will treat the component as a synchronous transformation.
<OutputBuffer Name="Output0" IsSynchronous="false">
Good me on commenting my code
<OutputBuffers>
<!--
Define what your buffer is called and what it looks like
Must set IsSynchronous as false. Otherwise it is a transformation
(one row enters, one row leaves) and not a source.
-->
<OutputBuffer Name="DemoOutput" IsSynchronous="false">
<Columns>
<Column Name="SourceColumn" DataType="String" Length="50" />
</Columns>
</OutputBuffer>
</OutputBuffers>
I am using BizTalk pipeline with JSON encoder to convert XML to JSON .
I have created the XSD but the JSON generated has #text instead of just a value for my elements.
Any ideas what I'm doing wrong?
<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://BookingEngine.Schemas.JSONSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" name="affiliate_reference_id" type="xs:unsignedShort" />
<xs:element minOccurs="1" name="hold" type="xs:boolean" />
<xs:element minOccurs="1" maxOccurs="unbounded" name="rooms">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" name="email" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="1" maxOccurs="unbounded" name="payments">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" name="type" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="1" name="affiliate_metadata" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
is converted to the following JSON
{
"affiliate_reference_id": {
"#text": "4480"
},
"hold": {
"#text": "false"
},
"rooms": [
{
"email": "john#example.com"
}
],
"payments": [
{
"type": "customer_card"
}
]
}
expected results would be
{
"affiliate_reference_id": "4480",
"hold": "false",
"rooms": [
{
"email": "john#example.com"
}
],
"payments": [
{
"type": "customer_card"
}
]
}
Any idea why the #text is popping up and how to remove it?
What do I need to change in my XSD schema?
I've the same result in c# when using Newtonsoft. The #text nodes are added when they have a different namespace than the root-namespace because in JSON it becomes an object with a text and a attribute namespace.
I added a custom biztalk pipeline and used json newton soft nuget package .
I created a pipeline with a JSON encoder and had this same issue.
The secret is you need to add an XML encoder before the JSON encoder in your pipeline. Yes, it's odd.
Create a schema with the correct data types for the JSON results you want. Add that schema to the XML encoder document schema property. The schema allows you to control how the JSON encoder works.
Note: XML requires a single root node but JSON does not. In your JSON assembly schema create a root node with any name you like. In the JSON encoder there's a check box to remove the root node enclosing the payload.
Javascript data types are not the same as XML (such as dates) so some translation may be needed.