Closed janrygh closed 6 years ago
I've done a small change in last release. I'm extremely if it has broken your already running code. Now the node look like this;
function(tagname, parent, val) {
this.tagname = tagname;
this.parent = parent;
this.child = {};//child tags
this.attrsMap = {};//attributes map
this.val = val;//text only
this.addChild = function(child) {
if (this.child[child.tagname]) {//already presents
this.child[child.tagname].push(child);
} else {
this.child[child.tagname] = [child];
}
};
};
Previously, child property of a node was pointing to single value or it was an array. Now child property of a node is always an object where the keys of child are nested tag names, pointing to an array of nodes.
OK, I just started using your library three weeks ago and found it perfect for my pruposes, since I need to parse large XMLs. But part of the parsing is iterating over the children tags in a ordered way. Seems like that possibility dissapeared with the rewrite to children as object instead of array. Any chance to get children tags as iterable array?
If I'm understanding your problem correctly, you can use Object.keys(nodechild)
to iterate child tags. But you'll not get it directly from the traversal object.
Though I could have kept it as an array instead of object but it helps me when I do further parsing to json or nimn (निम्न).
So someone need to suffer..either me..or you :wink:
Thanks, you guess you are right, I can probably use Object.keys(tObj.child)
Of course it is me that should suffer, I am just surfing on your work.
One more question:
var xmlParser = require('fast-xml-parser');
const XML_PARSER_OPTIONS = {
attributeNamePrefix : "",
attrNodeName: "attr", //default is 'false'
textNodeName : "",
ignoreAttributes : false,
ignoreNameSpace : false,
allowBooleanAttributes : false,
parseNodeValue : false,
parseAttributeValue : false,
trimValues: true,
decodeHTMLchar: true,
cdataTagName: "__cdata", //default is 'false'
cdataPositionChar: "\\c",
};
const myXml = '<tag><x>1</x><y>4</y><x>2</x></tag>';
const j = xmlParser.parse(myXml, XML_PARSER_OPTIONS);
const Parser = new xmlParser.j2xParser( XML_PARSER_OPTIONS );
const xml = Parser.parse(j)
I get "<tag y=\"4\"><x>1</x><x>2</x></tag>" out
The element y is turned into an attribute.
what I can see here is that invalid XML is being parsed. You should have used validator in such case. You can get more detail about that on README.
Hmm, I do not see what you mean. xmlParser.validate(myXml) gives true.
The return value is:
<tag y="4"><x>1</x><x>2</x></tag>
maybe it was the string representation you ment.
The point is that the element y is turned into an attribute.
This happens when attributeNamePrefix : "", not when it is set to ie attributeNamePrefix : "@_"
The previous comment is edited. Now I can read it correctly.
When you transform JSON to XML back, you'll have to set appropriate options properly. E.g. in this case, you should set either ignoreAttributes:true
or attributeNamePrefix
to some unique prefix.
The reason I've provided multiple options while parsing is to get almost same XML. So I don't see any issue here.
Ok, thanks.
I'll play around with it and see what suits us best.
Checklist
Please fill below checklist
Input data
Please include your sample code here
const XML_PARSER_OPTIONS = { attributeNamePrefix : "", attrNodeName: "attr", //default is 'false' textNodeName : "", ignoreAttributes : false, ignoreNameSpace : false, allowBooleanAttributes : false, parseNodeValue : true, parseAttributeValue : true, trimValues: true, decodeHTMLchar: false, cdataTagName: "__cdata", //default is 'false' cdataPositionChar: "\c", }; const myXml = ' ';
const tObj = xmlParser.getTraversalObj(myXml, XML_PARSER_OPTIONS);
tObj.child.toptag[0].child.forEach((nodeObj) => {
console.log(nodeObj.tagname);
});
Code
Output data
Please include output data here tObj.child.toptag[0].child.forEach is not a function
expected data
Please include expected output data here mychild mydog mycat mydog