Skip to content

Multiple roots support for XML parsing#796

Open
Vatsalsoni13 wants to merge 3 commits intoNaturalIntelligence:masterfrom
Vatsalsoni13:multipleRoots
Open

Multiple roots support for XML parsing#796
Vatsalsoni13 wants to merge 3 commits intoNaturalIntelligence:masterfrom
Vatsalsoni13:multipleRoots

Conversation

@Vatsalsoni13
Copy link

@Vatsalsoni13 Vatsalsoni13 commented Mar 3, 2026

Purpose / Goal

Multiple roots parsing support

Summary

Added a validation check in the XML parser to detect the presence of multiple root elements (i.e., more than one top-level node). If multiple roots are found, the parser reports the names of those root elements.

Changes Introduced

  • Introduced a new parser option:
    • multipleRoots (boolean, default: false)
    • When set to true, the parser allows XML documents with more than one root element.
  • By default (multipleRoots: false), the parser iterates over xmlObj.child and validates that only a single root node exists.
  • If multiple roots are detected, the parser reports their names in the error.

Observations(Not related to above changes directly)

The existing validate function in validator.js already attempts to detect multiple roots. However, it does not cover all cases:

  • <ABC/><TEST/> is not caught by validate
  • <ABC/><TEST> is caught under multiple roots
    I have added the check in the parser only and not in validate function. This can also be added but i understand that the validate function isn't taking any options.

Fixes #754

Test results

Before

----------------------------------|---------|----------|---------|---------|------------------------
File                              | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s      
----------------------------------|---------|----------|---------|---------|------------------------
All files                         |   97.73 |    96.66 |   96.84 |   97.73 |                        
 spec                             |   99.71 |    99.77 |     100 |   99.71 |                        
  arrayMode_spec.js               |     100 |      100 |     100 |     100 |                        
  attrIgnore_spec.js              |     100 |      100 |     100 |     100 |                        
  attr_spec.js                    |     100 |      100 |     100 |     100 |                        
  cdata_spec.js                   |     100 |      100 |     100 |     100 |                        
  comments_spec.js                |     100 |      100 |     100 |     100 |                        
  data_spec.js                    |     100 |      100 |     100 |     100 |                        
  entities_security_spec.js       |     100 |      100 |     100 |     100 |                        
  entities_spec.js                |     100 |      100 |     100 |     100 |                        
  html_spec.js                    |     100 |      100 |     100 |     100 |                        
  inputType_spec.js               |     100 |      100 |     100 |     100 |                        
  langbarrier_spec.js             |     100 |      100 |     100 |     100 |                        
  large_spec.js                   |     100 |      100 |     100 |     100 |                        
  nfr_spec.js                     |     100 |      100 |     100 |     100 |                        
  pi_spec.js                      |     100 |      100 |     100 |     100 |                        
  startIndex_spec.js              |     100 |      100 |     100 |     100 |                        
  stopNodes_spec.js               |     100 |      100 |     100 |     100 |                        
  transform_attributes_spec.js    |     100 |      100 |     100 |     100 |                        
  transform_tagname_spec.js       |     100 |      100 |     100 |     100 |                        
  unpairedTags_spec.js            |     100 |      100 |     100 |     100 |                        
  updateTag_spec.js               |     100 |      100 |     100 |     100 |                        
  validator_spec.js               |     100 |      100 |     100 |     100 |                        
  validator_utf8_with_BOM_spec.js |     100 |      100 |     100 |     100 |                        
  valueProcessors_spec.js         |   99.69 |    95.23 |     100 |   99.69 | 186                    
  x2j_str_spec.js                 |   33.33 |      100 |     100 |   33.33 | 8-25                   
  x_cyrillic_2j_str_spec.js       |     100 |      100 |     100 |     100 |                        
  xmlParser_spec.js               |     100 |      100 |     100 |     100 |                        
 src                              |    97.6 |    98.46 |   89.47 |    97.6 |                        
  fxp.js                          |     100 |      100 |     100 |     100 |                        
  ignoreAttributes.js             |     100 |      100 |     100 |     100 |                        
  util.js                         |   81.39 |      100 |      60 |   81.39 | 34-35,38-43            
  validator.js                    |   99.05 |    98.26 |     100 |   99.05 | 185-188                
 src/xmlbuilder                   |     100 |      100 |     100 |     100 |                        
  json2xml.js                     |     100 |      100 |     100 |     100 |                        
 src/xmlparser                    |   88.55 |    92.47 |   97.87 |   88.55 |                        
  DocTypeReader.js                |   64.45 |    86.25 |      90 |   64.45 | ...238,241-242,252-365 
  OptionsBuilder.js               |   96.59 |    93.75 |     100 |   96.59 | 76-78                  
  OrderedObjParser.js             |   97.53 |    94.91 |     100 |   97.53 | ...464,682-683,716-717 
  XMLParser.js                    |   95.77 |    90.47 |     100 |   95.77 | 23-24,52               
  node2json.js                    |   99.18 |    95.74 |     100 |   99.18 | 38                     
  xmlNode.js                      |    97.5 |       75 |     100 |    97.5 | 6                      
----------------------------------|---------|----------|---------|---------|------------------------

After

----------------------------------|---------|----------|---------|---------|------------------------
File                              | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s      
----------------------------------|---------|----------|---------|---------|------------------------
All files                         |   97.88 |    96.85 |   96.84 |   97.88 |                        
 spec                             |   99.73 |    99.79 |     100 |   99.73 |                        
  arrayMode_spec.js               |     100 |      100 |     100 |     100 |                        
  attrIgnore_spec.js              |     100 |      100 |     100 |     100 |                        
  attr_spec.js                    |     100 |      100 |     100 |     100 |                        
  cdata_spec.js                   |     100 |      100 |     100 |     100 |                        
  comments_spec.js                |     100 |      100 |     100 |     100 |                        
  data_spec.js                    |     100 |      100 |     100 |     100 |                        
  entities_security_spec.js       |     100 |      100 |     100 |     100 |                        
  entities_spec.js                |     100 |      100 |     100 |     100 |                        
  html_spec.js                    |     100 |      100 |     100 |     100 |                        
  inputType_spec.js               |     100 |      100 |     100 |     100 |                        
  langbarrier_spec.js             |     100 |      100 |     100 |     100 |                        
  large_spec.js                   |     100 |      100 |     100 |     100 |                        
  multipleRoots_spec.js           |     100 |      100 |     100 |     100 |                        
  nfr_spec.js                     |     100 |      100 |     100 |     100 |                        
  pi_spec.js                      |     100 |      100 |     100 |     100 |                        
  startIndex_spec.js              |     100 |      100 |     100 |     100 |                        
  stopNodes_spec.js               |     100 |      100 |     100 |     100 |                        
  transform_attributes_spec.js    |     100 |      100 |     100 |     100 |                        
  transform_tagname_spec.js       |     100 |      100 |     100 |     100 |                        
  unpairedTags_spec.js            |     100 |      100 |     100 |     100 |                        
  updateTag_spec.js               |     100 |      100 |     100 |     100 |                        
  validator_spec.js               |     100 |      100 |     100 |     100 |                        
  validator_utf8_with_BOM_spec.js |     100 |      100 |     100 |     100 |                        
  valueProcessors_spec.js         |   99.69 |    95.23 |     100 |   99.69 | 186                    
  x2j_str_spec.js                 |   33.33 |      100 |     100 |   33.33 | 8-25                   
  x_cyrillic_2j_str_spec.js       |     100 |      100 |     100 |     100 |                        
  xmlParser_spec.js               |     100 |      100 |     100 |     100 |                        
 src                              |    97.6 |    98.46 |   89.47 |    97.6 |                        
  fxp.js                          |     100 |      100 |     100 |     100 |                        
  ignoreAttributes.js             |     100 |      100 |     100 |     100 |                        
  util.js                         |   81.39 |      100 |      60 |   81.39 | 34-35,38-43            
  validator.js                    |   99.05 |    98.26 |     100 |   99.05 | 185-188                
 src/xmlbuilder                   |     100 |      100 |     100 |     100 |                        
  json2xml.js                     |     100 |      100 |     100 |     100 |                        
 src/xmlparser                    |   88.74 |    92.68 |   97.87 |   88.74 |                        
  DocTypeReader.js                |   64.45 |    86.25 |      90 |   64.45 | ...238,241-242,252-365 
  OptionsBuilder.js               |   96.62 |    93.75 |     100 |   96.62 | 77-79                  
  OrderedObjParser.js             |    97.6 |    95.16 |     100 |    97.6 | ...487,705-706,739-740 
  XMLParser.js                    |   95.77 |    90.47 |     100 |   95.77 | 23-24,52               
  node2json.js                    |   99.18 |    95.74 |     100 |   99.18 | 38                     
  xmlNode.js                      |    97.5 |       75 |     100 |    97.5 | 6                      
----------------------------------|---------|----------|---------|---------|------------------------

Type

Please mention the type of PR

  • Bug Fix
  • Refactoring / Technology upgrade
  • New Feature

Note : Please ensure that you've read contribution guidelines before raising this PR. If your PR is in progress, please prepend [WIP] in PR title. Your PR will be reviewed when [WIP] will be removed from the PR title.

Bookmark this repository for further updates.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

An option to optionally support muliple roots

1 participant