Problem with comments in XML files

26 views (last 30 days)
Bob
Bob on 24 Jul 2025
Commented: Bob on 28 Jul 2025
I have an m-file that reads an XML file to get inputs. I'm running into a problem with comments in the XML file. Simply put, if I put a comment inside the tag but before the value, then I get an empty string for the value. Comments elsewhere don't cause problems
Here's a toy example of my m-file:
function userInputStruct = readToyXmlInput()
toyXmlInputFile = 'toyXmlInput.xml';
xDoc = xmlread(toyXmlInputFile);
userInput = xDoc.getElementsByTagName('userInput');
userInputStruct = struct(); % Initialize
thisUserInput = userInput.item(0);
thisInput_01 = thisUserInput.getElementsByTagName('input_01');
thisInput_01Element = thisInput_01.item(0);
temp01 = thisInput_01Element.getFirstChild.getData;
temp02 = string(temp01);
input_01 = strip(temp02);
userInputStruct.input_01 = input_01;
Here's a toy example of my XML file:
<toyXmlInput>
<userInput>
<!-- A comment here is fine. -->
<input_01>
Dummy input #1 <!-- A comment here is fine. -->
<!-- A comment here is fine. -->
</input_01>
</userInput>
</toyXmlInput>
Here's a toy example of my XML file with a comment that causes a problem.
<toyXmlInput>
<userInput>
<input_01>
<!-- A comment here causes problems -->
Dummy input #1
</input_01>
</userInput>
</toyXmlInput>
What am I doing wrong? What can I do differently so that comments after the tag but before the value don't cause problems?
Worst-case, I'll just document in the m-file and the XML file that there's a limit on where comments can go. However, I'd prefer a more elegant solution.

Accepted Answer

Stephen23
Stephen23 on 24 Jul 2025
Edited: Stephen23 on 25 Jul 2025
The issue you're encountering is related to how XML Document Object Model (DOM) parsing handles different types of nodes within an element. When you use getFirstChild, you're getting the very first child node, which could be a text node, comment node, or element node. In your problematic case, the first child is a comment node, not the text content you want.
Here's what's happening:
  1. In your working XML, the first child of <input_01> is a text node (even if it's just whitespace before "Dummy input #1")
  2. In your problematic XML, the first child is a comment node, so getFirstChild.getData returns empty
XML Node Types:
  • Node Type 1: Element node (like <input_01>)
  • Node Type 3: Text node (the actual text content)
  • Node Type 4: CDATA section
  • Node Type 8: Comment node (what's causing your problem)
Solution:
Use getTextContent() - this is the simplest and most elegant solution. Replace your current line:
temp01 = thisInput_01Element.getFirstChild.getData;
With:
temp01 = thisInput_01Element.getTextContent;
The getTextContent() method automatically:
  • Concatenates all text content within the element
  • Ignores comments, processing instructions, and other non-text nodes
  • Handles nested elements properly
The getTextContent() approach will work with both of your XML examples and is the standard way to extract text content from XML elements while ignoring comments.
  1 Comment
Bob
Bob on 24 Jul 2025
Thanks! I obviously didn't know about getTextContent(). That method's doing exactly what I want and need.

Sign in to comment.

More Answers (1)

Steven Lord
Steven Lord on 24 Jul 2025
Do you need the comments to be imported? If not, and if upgrading to release R2020b or later is an option, consider using readstruct to read the contents of the XML file into a struct array. I've attached xmlfile1.txt and xmlfile2.txt as your two toy XML files. [I can't attach the files as .xml.] But I copy them into XML files with the first two lines.
copyfile xmlfile1.txt xmlfile1.xml
copyfile xmlfile2.txt xmlfile2.xml
The comments are not present in the data1 and data2 struct arrays, but the data is present.
data1 = readstruct('xmlfile1.xml')
data1 = struct with fields:
userInput: [1×1 struct]
data1.userInput
ans = struct with fields:
input_01: "Dummy input #1"
data2 = readstruct('xmlfile2.xml')
data2 = struct with fields:
userInput: [1×1 struct]
data2.userInput
ans = struct with fields:
input_01: "Dummy input #1"
  3 Comments
Stephen23
Stephen23 on 26 Jul 2025
Edited: Stephen23 on 26 Jul 2025
Use the Contents browser on the left hand side to navigate the documentation.

Sign in to comment.

Tags

Products


Release

R2018a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!