[x3d-public] Request for X3D encoding comment output from X3DPSAIL

John Carlson yottzumm at gmail.com
Mon Jan 5 11:49:29 PST 2026


Here’s a trial balloon:


import org.xml.sax.SAXException;
import org.xml.sax.ext.DefaultHandler2;
import java.io.IOException;
import java.io.Writer;
import java.util.regex.Pattern;

public class CommentNormalizingHandler extends DefaultHandler2 {
private Writer writer;
private Pattern attributeWithNewlinePattern;

public CommentNormalizingHandler(Writer writer) {
this.writer = writer;
// Matches newlines inside quoted attribute values
this.attributeWithNewlinePattern =
Pattern.compile("['\"][^'\"]*\\n[^'\"]*['\"]");
}

@Override
public void comment(char[] ch, int start, int length) throws SAXException {
try {
String commentText = new String(ch, start, length);

// Check if comment contains newlines inside attribute values
if (attributeWithNewlinePattern.matcher(commentText).find()) {
// Normalize whitespace but keep as single comment
String normalized = commentText.trim().replaceAll("\\s+", " ");
writer.write("<!--");
writer.write(normalized);
writer.write("-->");
} else {
// Split into multiple single-line comments
String[] lines = commentText.split("\\n");
for (String line : lines) {
String trimmed = line.trim();
if (!trimmed.isEmpty()) {
writer.write("<!--");
writer.write(trimmed);
writer.write("-->");
}
}
}
} catch (IOException e) {
throw new SAXException("Error writing comment", e);
}
}

@Override
public void startElement(String uri, String localName, String qName,
org.xml.sax.Attributes attributes) throws SAXException {
try {
writer.write("<");
writer.write(qName);

for (int i = 0; i < attributes.getLength(); i++) {
writer.write(" ");
writer.write(attributes.getQName(i));
writer.write("='");
writer.write(escapeXml(attributes.getValue(i)));
writer.write("'");
}

writer.write(">");
} catch (IOException e) {
throw new SAXException("Error writing start element", e);
}
}

@Override
public void endElement(String uri, String localName, String qName) throws
SAXException {
try {
writer.write("</");
writer.write(qName);
writer.write(">");
} catch (IOException e) {
throw new SAXException("Error writing end element", e);
}
}

@Override
public void characters(char[] ch, int start, int length) throws
SAXException {
try {
writer.write(escapeXml(new String(ch, start, length)));
} catch (IOException e) {
throw new SAXException("Error writing characters", e);
}
}

@Override
public void startDocument() throws SAXException {
try {
writer.write("<?xml version='1.0' encoding='UTF-8'?>");
} catch (IOException e) {
throw new SAXException("Error writing start document", e);
}
}

@Override
public void processingInstruction(String target, String data) throws
SAXException {
try {
writer.write("<?");
writer.write(target);
if (data != null && !data.isEmpty()) {
writer.write(" ");
writer.write(data);
}
writer.write("?>");
} catch (IOException e) {
throw new SAXException("Error writing processing instruction", e);
}
}

private String escapeXml(String text) {
return text.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace("'", "'")
.replace("\"", """);
}
}

// Enjoy!

John
On Mon, Jan 5, 2026 at 1:43 PM John Carlson <yottzumm at gmail.com> wrote:

> What comment parsing requires in Java SAXParser is handling the comment
> method in a subclass of DefaultHandler2:
>
>
> https://docs.oracle.com/javase/8/docs/api/org/xml/sax/ext/DefaultHandler2.html
>
>
> This should be handy enough to replace newlines inside an attribute inside
> a comment different from other newlines in a comment.
>
> Not ideal yet. Feel free to deploy extra test cases while “code” it up.
>
> John
>
> On Sun, Jan 4, 2026 at 4:01 PM John Carlson <yottzumm at gmail.com> wrote:
>
>> My current plan for replacing multiple line comments with single lines
>> comments where the comment content are preserved on separate lines is as
>> follows:
>>
>> 1.  Write a Java SAX parser to replace newlines with —>\n<!— inside XML
>> comments.
>>
>> 2.  Compile with GraalVM native-image into rnl.exe, if not taken.
>>
>> Write a script to apply to all original .x3d files in my examples.  This
>> will call vim or ex (vim command-line), with the command, %!rnl.exe, then
>> save and exit.
>>
>> If needed, I will include carriage return.
>>
>> Others would try to make this a stylesheet, but I don’t know if comment()
>> can be split on newlines in XSLT.   So I’ll ask claude.ai again!
>>
>> <xsl:stylesheet version="2.0" xmlns:xsl="
>> http://www.w3.org/1999/XSL/Transform">
>>
>> <xsl:template match="@*|node()">
>> <xsl:copy>
>> <xsl:apply-templates select="@*|node()"/>
>> </xsl:copy>
>> </xsl:template>
>>
>> <xsl:template match="comment()">
>> <xsl:for-each select="tokenize(., '&#xA;')">
>> <xsl:if test="normalize-space(.) != ''">
>> <xsl:comment><xsl:value-of select="normalize-space(.)"/></xsl:comment>
>> </xsl:if>
>> </xsl:for-each>
>> </xsl:template>
>>
>> </xsl:stylesheet>
>>
>> Gobbledegook to me, but maybe someone can use it.
>>
>> John
>>
>> On Sun, Jan 4, 2026 at 3:32 PM John Carlson <yottzumm at gmail.com> wrote:
>>
>>> For example, it nearly requires program to do this in Python or Perl.
>>>
>>> Claude.ai reports:
>>>
>>> perl -i -0pe 's/<!--(.*?)-->/join("\n", map {"<!-- $_ -->"} grep
>>> {s|^\s*||; s|\s*$||; $_} split("\n", $1))/gse' file.xml
>>>
>>> Obviously I can put this in a shell script, but I like stuff I can
>>> understand!
>>>
>>> Something in Java would be great!  Maybe I’ll write and contribute if it
>>> doesn’t already exist?
>>>
>>> Seems like a simple SAX parser, frankly!
>>>
>>> John
>>>
>>> On Sun, Jan 4, 2026 at 3:10 PM John Carlson <yottzumm at gmail.com> wrote:
>>>
>>>> Thanks, it wasn’t clear to me that multi-line comments were not
>>>> supported in X3D XML encoding.  That clears up most of my questions!
>>>>
>>>> I will replace multi-line comments with single-line comments in my
>>>> examples.   Does X3D-Edit support this feature?  This would be great, and
>>>> encourage me to use it!
>>>>
>>>> John
>>>>
>>>> On Sun, Jan 4, 2026 at 2:46 PM Don Brutzman <don.brutzman at gmail.com>
>>>> wrote:
>>>>
>>>>> For clarity, here is a recap of key points that can be found in prior
>>>>> responses and ticket issues:
>>>>>
>>>>>    - Persistent single-line comments are an important feature for X3D
>>>>>    model conversions and interoperability.
>>>>>    - You are welcome to use all Python features, including multi-line
>>>>>    comments, whenever programming with Python and x3d.py.
>>>>>    - Individual multi-line comments are not supported in a number of
>>>>>    file encodings and programming languages.  Nor are they defined by X3D
>>>>>    Architecture, nor are they supported by several X3D encodings (such as XML
>>>>>    and ClassicVRML).  Thus multi-line comments are not a required feature.
>>>>>    - Persistent comments in x3d.py Python are already supported via a
>>>>>    Comment class.
>>>>>    - Persistent single-line comments are now partially supported by
>>>>>    X3dToPython.xslt converter, if present as children of Scene head and
>>>>>    grouping nodes.  Further future work on content-model representations in
>>>>>    the Python class hierarchy may be able to add them elsewhere (e.g. inside
>>>>>    Shape Appearance Material geometry etc.
>>>>>    - Tickets are closed after careful review if they are unrepeatable
>>>>>    or unactionable.  Suggestions and questions about a clearer ticket are
>>>>>    usually included.
>>>>>
>>>>> Hope this helps.
>>>>>
>>>>> all the best, Don
>>>>> --
>>>>> X3D Graphics, Maritime Robotics, Distributed Simulation
>>>>> Relative Motion Consulting  https://RelativeMotion.info
>>>>>
>>>>>
>>>>> On Sun, Jan 4, 2026 at 5:57 AM John Carlson <yottzumm at gmail.com>
>>>>> wrote:
>>>>>
>>>>>> Blowing off some steam.  Apologies, I probably should work out
>>>>>> instead.
>>>>>>
>>>>>> I am unsure if it’s easier to output straight line code instead of
>>>>>> hierarchical code in Python; multi-line non-persistent comments might
>>>>>> become easier in straight line code.  I don’t know about comments() in
>>>>>> XSLT.  In straight line code, wrapping a multi or single line comment in
>>>>>> “””…””” is a cinch.  Even if newlines need to be added for the Python
>>>>>> interpreter.
>>>>>> AFAIK, I’ve already mentioned that straight line code is easier to
>>>>>> debug, in my mind.  I think the Java large file discussion is still
>>>>>> open; I know hierarchical code is more succinct, and less likely to stack
>>>>>> overflow.  I think the choices between code structure in Python and Java
>>>>>> might be different.
>>>>>>
>>>>>> Persistent multi-line comments are desirable, even if they aren’t
>>>>>> present in the archive.  We will probably make different choices between
>>>>>> hierarchical and straight line code when this feature is available.
>>>>>>
>>>>>> Short term hacks like single line comments work until features are
>>>>>> introduced.  That doesn’t mean tickets should be closed prematurely, or
>>>>>> examples outside the archives are invalid.
>>>>>>
>>>>>> John
>>>>>>
>>>>>> On Tue, Dec 30, 2025 at 3:42 AM John Carlson <yottzumm at gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> Don, thanks for your comment on this ticket that naively adding
>>>>>>> Comment to a children field might not work.  That was one of my intentions
>>>>>>> on expressing myself so vocally.  I apologize for using your time to do
>>>>>>> this, but I think it revealed a possible design consideration.  I think if
>>>>>>> I had discovered it, it would have gone over like a wet balloon.
>>>>>>>
>>>>>>> Thank you again, I will not put comments arbitrarily in the
>>>>>>> scenegraph for now with my PythonSerializer.js, until you indicate it’s
>>>>>>> ready!   I will leave them out of the scenegraph, as they are now.   Since
>>>>>>> I handle comments generically, I will have to research the nodes you’ve
>>>>>>> accomplished.
>>>>>>>
>>>>>>> Now, can we have other multi-line comments, not in the persistent
>>>>>>> scenegraph, in Python translated from .x3d, in the short term, like:
>>>>>>>
>>>>>>> #
>>>>>>> # This is comment line 2
>>>>>>> # This is comment line 3
>>>>>>> #
>>>>>>>
>>>>>>> ?
>>>>>>>
>>>>>>> John
>>>>>>>
>>>>>>> From the ticket:
>>>>>>>
>>>>>>>>>>>>>>
>>>>>>> This is not an easy fix for converting files because Comment is not
>>>>>>> part of the content model for all nodes. Solving this will probably require
>>>>>>> extending class _ X3DNode in x3d.py and sorting out possible subclass
>>>>>>> collisions. It will also be difficult to retain the original order of child
>>>>>>> nodes and child comments within a parent node.
>>>>>>>
>>>>>>> This might be fixable someday - after some effort I got it working
>>>>>>> for head, Scene, field, fieldValue.. Deferred as future work.
>>>>>>>>>>>>>>
>>>>>>> On Mon, Dec 29, 2025 at 12:52 PM Don Brutzman <
>>>>>>> don.brutzman at gmail.com> wrote:
>>>>>>>
>>>>>>>>
>>>>>>>> I have posted a new ticket to capture this point.  Perhaps a useful
>>>>>>>> exemplar, as well.
>>>>>>>>
>>>>>>>>    - X3D SourceForge ticket #82 creating persistent comments in
>>>>>>>>    python when converting from XML
>>>>>>>>    - https://sourceforge.net/p/x3d/tickets/82/
>>>>>>>>
>>>>>>>> Hope this helps.  Again thanks for your many efforts.  Have fun
>>>>>>>> improving X3D!  🤔 👍
>>>>>>>>
>>>>>>>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20260105/4a3bf695/attachment-0001.html>


More information about the x3d-public mailing list