NaturalIntelligence / fast-xml-parser

Validate XML, Parse XML and Build XML rapidly without C/C++ based libraries and no callback.
https://naturalintelligence.github.io/fast-xml-parser/
MIT License
2.5k stars 302 forks source link

V4 isArray will not parse single values as objects #466

Closed SpringsTea closed 2 years ago

SpringsTea commented 2 years ago

Description

I had been working on a project with v3 and wanted to add order preservation. I updated to v4 to use isArray along side this, with my goal being to get a single array of mixed tags in the order they appear in the xml. Here is an example xml:

<?xml version="1.0"?>
<Report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <ImageNode Name="Subjects Image">
    <Enabled>True</Enabled>
    <xPos>0.1875</xPos>
    <yPos>0.6146</yPos>
    <Width>0.7396</Width>
    <Height>1.0104001</Height>
    <Field>SubjectImage</Field>
  </ImageNode>
  <TextNode Name="Subjects First Name">
    <Enabled>True</Enabled>
    <xPos>0.9792</xPos>
    <yPos>0.7083</yPos>
    </EdgeText>
  </TextNode>
  <TextNode Name="Subjects Last Name">
    <Enabled>True</Enabled>
    <xPos>0.1771</xPos>
    <yPos>1.625</yPos>
  </TextNode>
</Report>

And my configuration:

const alwaysArray = [
    "TextNode",
    "ImageNode",
];

const xmloptions = {
    ignoreAttributes : false,
    ignoreNameSpace : false,
    allowBooleanAttributes : true,
    parseNodeValue : true,
    parseAttributeValue : true,
    trimValues: true,
    parseTrueNumberOnly: true,
    isArray: (name, jpath, isLeafNode, isAttribute) => { 
      if( alwaysArray.indexOf(name) !== -1) return true;
    },
    preserveOrder: true,
    stopNodes: ["parse-me-as-string"]
};

My expected output would be something like

[
 Report: [
    {
        ImageNode: {
            Enabled: true,
            xPos: 0.1875,
            yPos: 0.6146,
            Width: 0.7396,
            Height: 1.0104001,
            Field: 'Subject Image'
        }
    },
    {
        TextNode: {
            Enabled: true,
            xPos: 0.9792,
            yPos: 0.7083
        }
    },
    {
        TextNode: {
            Enabled: true,
            xPos: 0.1771,
            yPos: 1.625
        }
    }
 ]
]

But instead, all of children of ImageNode and TextNode are arrays, instead of objects.

{                                             
  TextNode: [                                 
    [Object], [Object],                       
    [Object]                             
  ],                                          
  ':@': { '@_Name': 'Subjects Barcode' }      
},                                            

When I was using V3, setting arrayMode to true would have all the child elements as single objects:

 {                                               
   '@_Name': 'Subjects Barcode',               
   Enabled: 'True',                                 
   xPos: 0.1771,                                 
   yPos: 1.7916
 },                                              

Even setting isArray to always return false, the children of TextNode will still be arrays. How can I achieve the array behavior I had in V3 in V4?

github-actions[bot] commented 2 years ago

I'm glad you find this repository helpful. I'll try to address your issue ASAP. You can watch the repo for new changes or star it.

amitguptagwl commented 2 years ago

@SpringsTea , If you want to preserve order, you should use probably preserveOrder property. Please check the docs. If you're facing issue while using isArray option. Let me check why it is not working for you.

amitguptagwl commented 2 years ago

This is working for me. I believe you're using some old version of FXP. please update and try again. Feel free to reopen the issue.