Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added "tabs" as possible value to asXML -indent and do the indentation with tabs, if given.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tabs
Files: files | file ages | folders
SHA3-256: cf00a7c8995ea0aa3ee75a511df63b3906c0ca6388fee69723dac0a8bb2175f7
User & Date: rolf 2020-07-22 00:49:26
Context
2020-07-22
23:42
Added -indent tabs to asJSON also. check-in: 4f33810032 user: rolf tags: tabs
00:49
Added "tabs" as possible value to asXML -indent and do the indentation with tabs, if given. check-in: cf00a7c899 user: rolf tags: tabs
2020-07-10
00:08
Minor documentation work. check-in: 57cf341505 user: rolf tags: trunk
Changes

Changes to doc/domDoc.xml.

107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
        <commanddef>
          <command><method>getDefaultOutputMethod</method></command>
          <desc>Returns the default output method of the document. This is
usually a result of a XSLT transformation.</desc>
        </commanddef>

      <commanddef>
        <command><method>asXML</method> <option>?-indent none/1..8?</option> <option>?-channel channelId?</option> <option>?-escapeNonASCII?</option> <option>?-doctypeDeclaration &lt;boolean&gt;?</option> <option>-xmlDeclaration &lt;boolean&gt;?</option> <option>-encString &lt;string&gt;</option> <option>?-escapeAllQuot?</option> <option>?-indentAttrs?</option> <option>?-nogtescape?</option> <option>?-noEmptyElementTag?</option></command>
        <desc><p>Returns the DOM tree as an (optional indented) XML
        string or sends the output directly to the given
        channelId.</p>

        <p>If the option <m>-escapeNonASCII</m> is given,
        every non 7 bit ASCII character in attribute values or element
        PCDATA content will be escaped as character reference in







|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
        <commanddef>
          <command><method>getDefaultOutputMethod</method></command>
          <desc>Returns the default output method of the document. This is
usually a result of a XSLT transformation.</desc>
        </commanddef>

      <commanddef>
        <command><method>asXML</method> <option>?-indent none/tabs/1..8?</option> <option>?-channel channelId?</option> <option>?-escapeNonASCII?</option> <option>?-doctypeDeclaration &lt;boolean&gt;?</option> <option>-xmlDeclaration &lt;boolean&gt;?</option> <option>-encString &lt;string&gt;</option> <option>?-escapeAllQuot?</option> <option>?-indentAttrs?</option> <option>?-nogtescape?</option> <option>?-noEmptyElementTag?</option></command>
        <desc><p>Returns the DOM tree as an (optional indented) XML
        string or sends the output directly to the given
        channelId.</p>

        <p>If the option <m>-escapeNonASCII</m> is given,
        every non 7 bit ASCII character in attribute values or element
        PCDATA content will be escaped as character reference in

Changes to generic/tcldom.c.

157
158
159
160
161
162
163


164
165
166
167
168
169
170
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
....
2872
2873
2874
2875
2876
2877
2878

2879




2880

2881
2882
2883
2884
2885
2886
2887
....
2908
2909
2910
2911
2912
2913
2914

2915




2916
2917
2918




2919
2920
2921
2922
2923
2924
2925
....
3003
3004
3005
3006
3007
3008
3009

3010




3011

3012
3013
3014
3015
3016
3017
3018
....
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479



3480
3481

3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499



3500
3501

3502
3503
3504
3505
3506
3507
3508
#define SERIALIZE_DOCTYPE_DECLARATION 2
#define SERIALIZE_FOR_ATTR 4 
#define SERIALIZE_ESCAPE_NON_ASCII 8
#define SERIALIZE_HTML_ENTITIES 16
#define SERIALIZE_ESCAPE_ALL_QUOT 32
#define SERIALIZE_NO_GT_ESCAPE 64
#define SERIALIZE_NO_EMPTY_ELEMENT_TAG 128



/*----------------------------------------------------------------------------
|   Module Globals
|
\---------------------------------------------------------------------------*/
#ifndef TCL_THREADS
    static int        storeLineColumn       = 0;
................................................................................
    "    getElementsByTagNameNS uri localname    \n"
    "    createElement tagName ?objVar?          \n"
    "    createElementNS uri tagName ?objVar?    \n"
    "    createCDATASection data ?objVar?        \n"
    "    createTextNode text ?objVar?            \n"
    "    createComment text ?objVar?             \n"
    "    createProcessingInstruction target data ?objVar? \n"
    "    asXML ?-indent <none,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
    "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
    "    asText                                  \n"
    "    asJSON ?-indent <none,0..8>?            \n"
    "    getDefaultOutputMethod                  \n"
    "    publicId ?publicId?                     \n"
    "    systemId ?systemId?                     \n"
    "    internalSubset ?internalSubset?         \n"
................................................................................
    "    baseURI ?URI?                \n"
    "    localName                    \n"
    "    delete                       \n"
    "    getLine                      \n"
    "    getColumn                    \n"
    "    @<attrName> ?defaultValue?   \n"
    "    asList                       \n"
    "    asXML ?-indent <none,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
    "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
    "    asText                       \n"
    "    asJSON ?-indent <none,0..8>? \n"
    "    appendFromList nestedList    \n"
    "    appendFromScript script      \n"
    "    insertBeforeFromScript script ref \n"
    "    appendXML xmlString          \n"
................................................................................
        writeChars(xmlString, chan, ((domTextNode*)node)->nodeValue,
                                    ((domTextNode*)node)->valueLength);
        writeChars(xmlString, chan, "]]>", 3);
        return;
    }

    if ((indent != -1) && doIndent) {

        for(i=0; i<level; i++) {




            writeChars(xmlString, chan, "        ", indent);

        }
    }

    if (node->nodeType == COMMENT_NODE) {
        writeChars(xmlString, chan, "<!--", 4);
        writeChars(xmlString, chan, ((domTextNode*)node)->nodeValue,
                                    ((domTextNode*)node)->valueLength);
................................................................................
    writeChars(xmlString, chan, node->nodeName, -1);

    attrs = node->firstAttr;
    while (attrs) {
        if (indentAttrs > -1) {
            writeChars(xmlString, chan, "\n", 1);
            if ((indent != -1) && doIndent) {

                for(i=0; i<level; i++) {




                    writeChars(xmlString, chan, "        ", indent);
                }
                if (indentAttrs) {




                    writeChars(xmlString, chan, "        ", indentAttrs);
                }
            }
        } else {
            writeChars(xmlString, chan, " ", 1);
        }
        writeChars(xmlString, chan, attrs->nodeName, -1);
................................................................................
                writeChars(xmlString, chan, ">", 1);
            } else {
                writeChars(xmlString, chan, "/>",   2);
            }
        }
    } else {
        if ((indent != -1) && hasElements) {

            for(i=0; i<level; i++) {




                writeChars(xmlString, chan, "        ", indent);

            }
        }
        writeChars (xmlString, chan, "</", 2);
        writeChars(xmlString, chan, node->nodeName, -1);
        if (indent != -1) {
            writeChars(xmlString, chan, ">\n", 2);
        } else {
................................................................................
            goto cleanup;
        }
        switch ((enum asXMLOption) optionIndex) {

        case m_indent:
            if (objc < 4) {
                SetResult("-indent must have an argument "
                          "(0..8 or 'no'/'none')");
                goto cleanup;
            }
            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }
            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }



            else if (Tcl_GetIntFromObj(interp, objv[3], &indent) != TCL_OK) {
                SetResult( "indent must be an integer (0..8) or 'no'/'none'");

                goto cleanup;
            }
            objc -= 2;
            objv += 2;
            break;

        case m_indentAttrs:
            if (objc < 4) {
                SetResult("-indentAttrs must have an argument "
                          "(0..8 or 'no'/'none')");
                goto cleanup;
            }
            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
                indentAttrs = -1;
            }
            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
                indentAttrs = -1;
            }



            else if (Tcl_GetIntFromObj(interp, objv[3], &indentAttrs) != TCL_OK) {
                SetResult( "indentAttrs must be an integer (0..8) or 'no'/'none'");

                goto cleanup;
            }
            if (indentAttrs > 8) indentAttrs = 8;
            if (indentAttrs < 0) indentAttrs = 0;
            objc -= 2;
            objv += 2;
            break;







>
>







 







|







 







|







 







>
|
>
>
>
>
|
>







 







>
|
>
>
>
>
|
|
<
>
>
>
>







 







>
|
>
>
>
>
|
>







 







|








>
>
>

|
>









|








>
>
>

|
>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
....
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
....
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930

2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
....
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
....
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
#define SERIALIZE_DOCTYPE_DECLARATION 2
#define SERIALIZE_FOR_ATTR 4 
#define SERIALIZE_ESCAPE_NON_ASCII 8
#define SERIALIZE_HTML_ENTITIES 16
#define SERIALIZE_ESCAPE_ALL_QUOT 32
#define SERIALIZE_NO_GT_ESCAPE 64
#define SERIALIZE_NO_EMPTY_ELEMENT_TAG 128
#define SERIALIZE_INDENT_WITH_TAB 256
#define SERIALIZE_INDENT_ATTR_WITH_TAB 512

/*----------------------------------------------------------------------------
|   Module Globals
|
\---------------------------------------------------------------------------*/
#ifndef TCL_THREADS
    static int        storeLineColumn       = 0;
................................................................................
    "    getElementsByTagNameNS uri localname    \n"
    "    createElement tagName ?objVar?          \n"
    "    createElementNS uri tagName ?objVar?    \n"
    "    createCDATASection data ?objVar?        \n"
    "    createTextNode text ?objVar?            \n"
    "    createComment text ?objVar?             \n"
    "    createProcessingInstruction target data ?objVar? \n"
    "    asXML ?-indent <none,tabs,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
    "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
    "    asText                                  \n"
    "    asJSON ?-indent <none,0..8>?            \n"
    "    getDefaultOutputMethod                  \n"
    "    publicId ?publicId?                     \n"
    "    systemId ?systemId?                     \n"
    "    internalSubset ?internalSubset?         \n"
................................................................................
    "    baseURI ?URI?                \n"
    "    localName                    \n"
    "    delete                       \n"
    "    getLine                      \n"
    "    getColumn                    \n"
    "    @<attrName> ?defaultValue?   \n"
    "    asList                       \n"
    "    asXML ?-indent <none,tabs,0..8>? ?-channel <channel>? ?-escapeNonASCII? ?-escapeAllQuot? ?-doctypeDeclaration <boolean>?\n"
    "    asHTML ?-channel <channelId>? ?-escapeNonASCII? ?-htmlEntities?\n"
    "    asText                       \n"
    "    asJSON ?-indent <none,0..8>? \n"
    "    appendFromList nestedList    \n"
    "    appendFromScript script      \n"
    "    insertBeforeFromScript script ref \n"
    "    appendXML xmlString          \n"
................................................................................
        writeChars(xmlString, chan, ((domTextNode*)node)->nodeValue,
                                    ((domTextNode*)node)->valueLength);
        writeChars(xmlString, chan, "]]>", 3);
        return;
    }

    if ((indent != -1) && doIndent) {
        if (outputFlags & SERIALIZE_INDENT_WITH_TAB) {
            for(i=0; i<level; i++) {
                writeChars(xmlString, chan, "\t", 1);
            }
        } else {
            for(i=0; i<level; i++) {
                writeChars(xmlString, chan, "        ", indent);
            }
        }
    }

    if (node->nodeType == COMMENT_NODE) {
        writeChars(xmlString, chan, "<!--", 4);
        writeChars(xmlString, chan, ((domTextNode*)node)->nodeValue,
                                    ((domTextNode*)node)->valueLength);
................................................................................
    writeChars(xmlString, chan, node->nodeName, -1);

    attrs = node->firstAttr;
    while (attrs) {
        if (indentAttrs > -1) {
            writeChars(xmlString, chan, "\n", 1);
            if ((indent != -1) && doIndent) {
                if (outputFlags & SERIALIZE_INDENT_WITH_TAB) {
                    for(i=0; i<level; i++) {
                        writeChars(xmlString, chan, "\t", 1);
                    }
                } else {
                    for(i=0; i<level; i++) {
                        writeChars(xmlString, chan, "        ", indent);
                    }

                }
                if (outputFlags & SERIALIZE_INDENT_ATTR_WITH_TAB) {
                    writeChars(xmlString, chan, "\t", 1);
                } else {
                    writeChars(xmlString, chan, "        ", indentAttrs);
                }
            }
        } else {
            writeChars(xmlString, chan, " ", 1);
        }
        writeChars(xmlString, chan, attrs->nodeName, -1);
................................................................................
                writeChars(xmlString, chan, ">", 1);
            } else {
                writeChars(xmlString, chan, "/>",   2);
            }
        }
    } else {
        if ((indent != -1) && hasElements) {
            if (outputFlags & SERIALIZE_INDENT_WITH_TAB) {
                for(i=0; i<level; i++) {
                    writeChars(xmlString, chan, "\t", 1);
                }
            } else {
                for(i=0; i<level; i++) {
                    writeChars(xmlString, chan, "        ", indent);
                }
            }
        }
        writeChars (xmlString, chan, "</", 2);
        writeChars(xmlString, chan, node->nodeName, -1);
        if (indent != -1) {
            writeChars(xmlString, chan, ">\n", 2);
        } else {
................................................................................
            goto cleanup;
        }
        switch ((enum asXMLOption) optionIndex) {

        case m_indent:
            if (objc < 4) {
                SetResult("-indent must have an argument "
                          "(0..8 or 'no'/'none'/'tabs')");
                goto cleanup;
            }
            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }
            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
                indent = -1;
            }
            else if (strcmp("tabs", Tcl_GetString(objv[3]))==0) {
                outputFlags |= SERIALIZE_INDENT_WITH_TAB;
            }
            else if (Tcl_GetIntFromObj(interp, objv[3], &indent) != TCL_OK) {
                SetResult( "indent must be an integer (0..8) or "
                           "'no'/'none'/'tabs'");
                goto cleanup;
            }
            objc -= 2;
            objv += 2;
            break;

        case m_indentAttrs:
            if (objc < 4) {
                SetResult("-indentAttrs must have an argument "
                          "(0..8 or 'no'/'none'/'tabs')");
                goto cleanup;
            }
            if (strcmp("none", Tcl_GetString(objv[3]))==0) {
                indentAttrs = -1;
            }
            else if (strcmp("no", Tcl_GetString(objv[3]))==0) {
                indentAttrs = -1;
            }
            else if (strcmp("tabs", Tcl_GetString(objv[3]))==0) {
                outputFlags |= SERIALIZE_INDENT_ATTR_WITH_TAB;
            }
            else if (Tcl_GetIntFromObj(interp, objv[3], &indentAttrs) != TCL_OK) {
                SetResult( "indentAttrs must be an integer (0..8) or "
                           "'no'/'none'/'tabs'");
                goto cleanup;
            }
            if (indentAttrs > 8) indentAttrs = 8;
            if (indentAttrs < 0) indentAttrs = 0;
            objc -= 2;
            objv += 2;
            break;

Changes to tests/domDoc.test.

315
316
317
318
319
320
321



































322
323
324
325
326
327
328
    set root [$doc documentElement]
    $root setAttribute attr "foo\"bar"
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc attr="foo&quot;bar"/>}




































set doc [dom parse <root/>]

test domDoc-2.1 {publicId - no publicId there} {
    $doc publicId
} {}

test domDoc-2.2 {systemId - no systemId there} {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
    set root [$doc documentElement]
    $root setAttribute attr "foo\"bar"
    set result [$doc asXML -indent none]
    $doc delete
    set result
} {<doc attr="foo&quot;bar"/>}

test domDoc-1.32 {asXML -indent tabs} {
    set doc [dom parse {<doc><a><b/></a></doc>}]
    set result [$doc asXML -indent tabs]
    $doc delete
    set result
} "<doc>\n\t<a>\n\t\t<b/>\n\t</a>\n</doc>\n"

test domDoc-1.33 {asXML -indent tabs} {
    set doc [dom parse {<doc><a><b/></a><c><d><f/></d></c><g/></doc>}]
    set result [$doc asXML -indent tabs]
    $doc delete
    set result
} "<doc>\n\t<a>\n\t\t<b/>\n\t</a>\n\t<c>\n\t\t<d>\n\t\t\t<f/>\n\t\t</d>\n\t</c>\n\t<g/>\n</doc>\n"

test domDoc-1.34 {asXML -indent tabs -noEmptyElementTag} {
    set doc [dom parse {<doc><a><b/></a><c><d><f/></d></c><g/></doc>}]
    set result [$doc asXML -indent tabs -noEmptyElementTag]
    $doc delete
    set result
} "<doc>\n\t<a>\n\t\t<b></b>\n\t</a>\n\t<c>\n\t\t<d>\n\t\t\t<f></f>\n\t\t</d>\n\t</c>\n\t<g></g>\n</doc>\n"

test domDoc-1.35 {asXML -indent tabs -indentAttrs tabs} {
    set doc [dom parse {<doc><a a1="a1" a2="a2"><b/></a><c><d a1="a1" a2="a2"><f/></d></c><g/></doc>}]
    set result [$doc asXML -indent tabs -indentAttrs tabs]
    $doc delete
    set result
} "<doc>\n\t<a\n\t\ta1=\"a1\"\n\t\ta2=\"a2\">\n\t\t<b/>\n\t</a>\n\t<c>\n\t\t<d\n\t\t\ta1=\"a1\"\n\t\t\ta2=\"a2\">\n\t\t\t<f/>\n\t\t</d>\n\t</c>\n\t<g/>\n</doc>\n"

test domDoc-1.36 {asXML -indent tabs -indentAttrs <num>} {
    set doc [dom parse {<doc><a a1="a1" a2="a2"><b/></a><c><d a1="a1" a2="a2"><f/></d></c><g/></doc>}]
    set result [$doc asXML -indent tabs -indentAttrs 2]
    $doc delete
    set result
} "<doc>\n\t<a\n\t  a1=\"a1\"\n\t  a2=\"a2\">\n\t\t<b/>\n\t</a>\n\t<c>\n\t\t<d\n\t\t  a1=\"a1\"\n\t\t  a2=\"a2\">\n\t\t\t<f/>\n\t\t</d>\n\t</c>\n\t<g/>\n</doc>\n"

set doc [dom parse <root/>]

test domDoc-2.1 {publicId - no publicId there} {
    $doc publicId
} {}

test domDoc-2.2 {systemId - no systemId there} {