Suppress formatting in XML files

Is there a way to suppress formatting in some sections of an XML file?  Most auto formatters I have used in the past ignore everything inside a CDATA tag, but this doesn't seem to work in IntelliJ.  I noticed a "Keep whitespace inside" option under Code Style -> XML -> Other -> CDATA, but it doesn't seem to do what I would expect it to do.

The main reason why I would like to have this is that we are using MyBatis, which keeps all your SQL statements in an xml file.  The default formatter works very well for the standard DML statements, but removes all indentation when you include a callable statement.

eg.
Original formatting I would like to preserve:
    <select id="findMemberClients" parameterType="clientParams" statementType="CALLABLE" useCache="false">
        <![CDATA[
        {
            call
                declare
                    i_arr HRV_ADMIN.INTEGER_ARRAY;
                    id_dsv VARCHAR(1000);
                begin
                    i_arr := pkg_harnessweb.getAllClientIds(#{clientId,mode=IN});
                    FOR i IN i_arr.FIRST .. i_arr.LAST
                    LOOP
                        id_dsv := id_dsv || i_arr(i) || '|';
                    END LOOP;
                    #{idsDsv,mode=OUT,jdbcType=VARCHAR} := id_dsv;
                end
        }
        ]]>
    </select>


After auto formatting:
    <select id="findMemberClients" parameterType="clientParams" statementType="CALLABLE" useCache="false">
        <![CDATA[
        {
        call declare
        i_arr HRV_ADMIN.INTEGER_ARRAY;
        id_dsv VARCHAR(1000);
        begin
        i_arr := pkg_harnessweb.getAllClientIds(#{clientId,mode=IN});
        FOR i IN i_arr.FIRST .. i_arr.LAST
        LOOP
        id_dsv := id_dsv || i_arr(i) || '|';
        END LOOP;
        #{idsDsv,mode=OUT,jdbcType=VARCHAR} := id_dsv;
        end
        }
        ]]>
    </select>

4 comments
Comment actions Permalink

What version are you running? In IDEA 11.0.2 there is a "preserve" option for XML CDATA. It is in the "whitespace around" drop down. See screenshot below. With this selection, I can take your original code, paste it in, do a "reformat code" action, and there is no change to the CDATA section. I remember this was a feature request a while back (as I had voted for it.)  I'm pretty sure it was this request: http://youtrack.jetbrains.com/issue/IDEA-21113  That was added in IDEA 10, about a year and a half ago. If you look at the end of that feature request, it explains what the options do.

screenshot.png

0
Comment actions Permalink

Thanks for getting back to me.  I am using 11.0.2 and I already had that option set.  Seeing your response made me look into it a bit more closely.

I now know that it works as expected in a clean XML file, but I had neglected to set up a clean test case.  I was using one of our actual files which has the following DocType declaration:
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD iBatis Mapper 3.0 //EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
This seems to alert IntelliJ that the file contains SQL.

If I change the SQL dialect to "Keywords only" for the file, the xml portions of the file format correctly and the data inside the CDATA tags is left alone, but the rest of my SQL code won't auto format.  If I change the dialect to any other value (I tested around 5 of them), the CDATA tags are ignored and I get the behaviour I described.

It looks to me that the SQL formatter is overriding the xml formatter.  It is not what I would expect to happen, but I can see how other people may view this as a feature, rather than a bug.

Should I be reporting this as a bug?

0
Comment actions Permalink

What you can do is uninject the language. Place your cursor in the CDATA area with the SQL, type Alt+Enter, and select "Uninject language" from the pop-up. IDEA will no longer treat that fragment as SQL. And therefore, it will no longer format it as anything other than  XML. You will also lose code SQL based code completion for the section as well. If you have a datasource configured (via the Data Sources tool window) you get full completion of your table and column names when editing SQL. A very useful feature.

If you want to turn off the automatic detection of the SQL fragments in your XML for all files (existing and future ones), go to File > Settings > Project Settings > Language Injections. Find the definition for the ibatis namespace you are using and disable it. Unfortunately, some of the names are not the best. But you can sort by SQL and then double click the listings (or click the edit button) to view the details. I found the ibatis name space you are using showing as "xml:select".

One other thing I should mention... the SQL formatter is a recent add and is still a bit rough, and basic. From my understanding, JetBrains is planing to make it more robust. And there are some feature requests related to that. For example, http://youtrack.jetbrains.com/issue/IDEA-79088 and http://youtrack.jetbrains.com/issue/IDEA-7397 Hopefully once those are in place, the SQL formatter would be able to be configured to do just what you want to the SQL and you can inject the SQL language back in.

0
Comment actions Permalink

That is exactly what I was after.  Thanks for providing such a detailed answer.

The SQL formatter might still be a little rough, but the process as a whole is significantly better that what I was getting with Eclipse.

0

Please sign in to leave a comment.