jOOQ/jOOX

Trouble writing CDATA. Getting HTML entity name instead of < and >

bespalhuk opened this issue · 8 comments

Never had trouble writing any content inside any tag, but now I'm facing this and I wouldn't like to call String.replace() before saving the XML file.

When Impl.text(Content content) is called, my value is "". Value is setted through match.setTextContent(text).
Before the method finishes, using debug, I saw the value of this.toString() and it is returning &lt and &gt. But if I call this.get(0), it returns my original value(having < and >).

I don't know if it is working as intended, maybe it is and I must look somewhere else.
Should I use a different approach or is there any configuration?

Thank you very much for reporting this. Could you perhaps show a full set of Java instructions that will help reproduce this as easily as possible? I'm not 100% sure how you generated this issue...

I will try to minimize, because it's all encapsulated.
I have an UrlQrCode class building my URL with all parameters I need, this class is implementing Content and inserting through String.format, like this...

    @Override
    public String content(Context context) {
        return String.format("<![CDATA[%s]]>", urlQrCode);
    }

After that, I build my XML block through Joox Impl.class, using Impl.text(Content content) method. Encapsulated code:

    public static NFeXml e(String elementName, Content content) {
        return new NFeXml(e(elementName).matches.stream()
                .map(m -> m.text(content))
                .collect(MoreCollectors.toImmutableList()));
    }

Joox.Impl(Content content)

    @Override
    public final Impl text(Content content) {
        final int size = size();

        for (int matchIndex = 0; matchIndex < size; matchIndex++) {
            Element match = get(matchIndex);
            String text = content.content(context(match, matchIndex, size));
            match.setTextContent(text);
        }

        return this;
    }

And then again, after the call, the variable String text inside the "for", is ecxatelly the URL I built plus around it, this.get(0).getTextContent() too. But this.toString() is returning the value formatted with HTML entities.

Aha, I see - I'm sorry for the confusion on my side. But you don't really need <![CDATA[...]]> as jOOX is already XML escaping all text content for you. This is formally correct, but perhaps not what you require.

Unfortunately, if you really want <![CDATA[...]]> output, this is currently not supported by jOOX...

Oh, ok... thanks. I will try a regex to replace all HTML entities within my QrCode tag.
Brazilian legislation requires output.

legislation requires that? Now, you've got me curious. Do you have a pointer to said legislation? And why is it different from content that is properly escaped?

Here in Brazil, things are made to be difficult hahaha.
If you try to validate a Nota Fiscal do Consumidor Eletrônica (NFC-e), it will be refused... already tried.
This rule is written in one of it's hundreds manuals... "this field content should be <! [CDATA [text]]>"

Oh, wow... Interesting to know! Well, jOOX internaly maintains an "ordinary" DOM. You could traverse the DOM and replace the relevant text nodes by CDATA nodes rather easily. Or do the same with XSLT as a post-processing instruction...

On the other hand, I think we should support CDATA natively in jOOQ. I've registered a feature request #140 for this, and will close this one here as a duplicate

Fixed #140. Feel free to check it out and build it yourself. We might still release the next version in December 2015, too.