Skip to content

CDATA is written with indentation and newlines #14

Closed

Description

@Hagedihag

I read the following XML with xml2json:

<?xml version="1.0"?>
<group>
	<name><![CDATA[An example name]]></name>
</group>

but writing it back with json2xml gives me:

<?xml version="1.0"?>
<group>
    <name>
        <![CDATA[My modified name]]>
    </name>
</group>

This is is not the expected XML output.
The CDATA section is not a TAG and should not be handled as one and therefore not be indented.
Sure, its easier to read, but its not 100% correct.
It would be great to fix that or make a config parameter for that behaviour.

example code:

var xmljs = require('xml-js');
var xmlIn = '<?xml version="1.0"?>\n<group>\n\t<name><![CDATA[An example name]]></name>\n</group>';
console.log('xmlIn:\n',xmlIn);

var jsonIn = xmljs.xml2json(xmlIn, {
	compact: true
});
var obj = JSON.parse(jsonIn);

// code to modify obj
obj.group.name._cdata = 'My modified name';

var jsonOut = JSON.stringify(obj);

var xmlOut = xmljs.json2xml(jsonOut, {
	compact	: true, 
	spaces	: 4,
	fullTagEmptyElement: true
});

console.log('xmlOut:\n',xmlOut);

Solution
file: js2xml.js

  1. Function: writeElementsCompact, Line 143
                case options.cdataKey: xml += writeCdata(element, options); break;
  1. Function: hasContent, Line 102
                case options.cdataKey:
                	return false;

Activity

  1. nashwaan commented on Apr 26, 2017

    @nashwaan
    Owner

    @brathering Are you sure CData should not be proceeded by spaces or indentation at all?

    I am thinking that there could be multiple CData inside an element:

    <?xml version="1.0"?>
    <group>
        <name>
            <![CDATA[My modified name 1]]>
            <![CDATA[My modified name 2]]>
            <![CDATA[My modified name 3]]>
        </name>
    </group>

    Following your proposal, they will be like this:

    <?xml version="1.0"?>
    <group>
        <name><![CDATA[My modified name 1]]><![CDATA[My modified name 2]]><![CDATA[My modified name 3]]></name>
    </group>
  2. Hagedihag commented on Apr 26, 2017

    @Hagedihag
    ContributorAuthor

    Yes, I'm quite sure, because CDATA is not a tag and can be used inline in text:

    <?xml version="1.0"?>
    <group>
      <name>The url <![CDATA[http://www.test.com]]> and name <![CDATA[examplename]]> are wrapped</name>
    </group>

    If you use xmllint to format the above xml, it also doesn't add spaces and indentation:

    $ xmllint --format test.xml
  3. nashwaan commented on Apr 26, 2017

    @nashwaan
    Owner

    Thanks for confirming this.

    I have published v1.1.0 which supports the suggested behavior.
    Also, to support old behavior, indentCdata: true flag can be set in options object.

    @brathering Please let me know whether the new result is as per your expectations or not.

  4. nashwaan commented on Apr 27, 2017

    @nashwaan
    Owner

    v1.1.0 is published now.

  5. Hagedihag commented on Apr 27, 2017

    @Hagedihag
    ContributorAuthor

    Thank you very much for the quick update, looks good now and works as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions