node-xml2js icon indicating copy to clipboard operation
node-xml2js copied to clipboard

#name Error: Invalid character in name

Open lengerrong opened this issue 4 years ago • 4 comments

preserveChildrenOrder (default false): Modifies the behavior of explicitChildren so that the value of the "children" property becomes an ordered array. When this is true, every node will also get a #name field whose value will correspond to the XML nodeName, so that you may iterate the "children" array and still be able to determine node names. The named (and potentially unordered) properties are also retained in this configuration at the same level as the ordered "children" array. Added in 0.4.9.

when we parser xml string with {preserveChildrenOrder:true} option, each node will add a "#name" field. but when we try to builder the js object back to string again, we got Error:

Error: Invalid character in name at XMLStringifier.module.exports.XMLStringifier.assertLegalName (node_modules/xml2js/node_modules/xmlbuilder/lib/XMLStringifier.js:213:15)

reproduce code:

  let originXml = '<a:p><a:pPr marL="0" lvl="0" indent="0" algn="ctr" rtl="0"><a:spcBef><a:spcPts val="0"/></a:spcBef><a:spcAft><a:spcPts val="0"/></a:spcAft><a:buClr><a:schemeClr val="dk1"/></a:buClr><a:buSzPts val="1100"/><a:buFont typeface="Arial"/><a:buNone/></a:pPr><a:r><a:rPr lang="ja-JP" altLang="en-US"/><a:t>first line</a:t></a:r><a:br><a:rPr lang="en-CA" altLang="ja-JP" dirty="0"/></a:br><a:r><a:rPr lang="ja-JP" altLang="en-US"/><a:t>second line</a:t></a:r><a:endParaRPr lang="ja-JP" altLang="en-US" dirty="0"/></a:p>'
  new xml2js.Parser({explicitChildren: true, preserveChildrenOrder:true}).parseString(originXml, function(err, js) {
    console.log(js)
    let builder = new xml2js.Builder({ renderOpts: { pretty: false }, headless: true});
    let newxml = builder.buildObject(js);
    console.log(originXml)
    console.log(newxml)
    console.log(originXml === newxml)
  });

lengerrong avatar Aug 05 '21 18:08 lengerrong

The parsed json object is like:

{
  'a:p': {
    '#name': 'a:p',
    '$$': [ [Object], [Object], [Object], [Object], [Object] ],
    'a:pPr': [ [Object] ],
    'a:r': [ [Object], [Object] ],
    'a:br': [ [Object] ],
    'a:endParaRPr': [ [Object] ]
  }
}

except '#name', '$$' will be consider as invalid TagName as well.

lengerrong avatar Aug 05 '21 18:08 lengerrong

it seems like xml2js.Builder didn't support preserveChildrenOrder:true option yet.

lengerrong avatar Aug 05 '21 18:08 lengerrong

The author of the library specifies this in the docs: At the moment, a one to one bi-directional conversion is guaranteed only for default configuration, except for attrkey, charkey and explicitArray options you can redefine to your taste.

sad but true.

ogomez92 avatar Sep 03 '21 15:09 ogomez92

HI, is there any work around for this?

jainkuniya avatar Dec 31 '22 14:12 jainkuniya