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

Changes In Branch TDOM_NS Excluding Merge-Ins

This is equivalent to a diff from 65c1350cd7 to 4cada4420f

2015-04-01
23:14
Added option -ignorexmlns to the dom parse method. check-in: 1fddc58c07 user: rolf tags: trunk
23:10
Initialize ignorexmlns for tdom cmd. Closed-Leaf check-in: 4cada4420f user: rolf tags: TDOM_NS
23:00
Merged from trunk. check-in: 4ac7a71245 user: rolf tags: TDOM_NS
22:40
Corrected typo. check-in: 65c1350cd7 user: rolf tags: trunk
22:12
Added new expat parser cmd method currentmarkup. check-in: 2b183ffd3f user: rolf tags: trunk

Changes to doc/dom.xml.

186
187
188
189
190
191
192


















193
194
195
196
197
198
199
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







value "never" means, that only the given XML source is parsed and no external
entity (including the external subset) will be resolved and parsed. The value
"notstandalone" means, that all external entities will be resolved and parsed,
with the execption of documents, which explicitly states standalone="yes" in
their XML declaration.</desc>
              </optdef>


              <optdef>
                <optname>-ignorexmlns</optname>
                <desc>It is recommended, that you not use this
                option. If this option is given, no node within the
                created DOM tree will be internally marked as placed
                into an XML Namespace, even if there is a default
                namespace in scope for un-prefixed elements or even if
                the element has a defined namespace prefix. One
                consequence is of this is, that XPath node expressions
                on such a DOM tree doesn't work as expected. Prefixed
                element nodes can't be selected and element nodes
                without prefix will be seen by XPath expressions as if
                they haven't any namespace (no matter if they in fact
                in a default namespace).
                </desc>
              </optdef>

            </optlist>
<p/>
</desc>
        </commanddef>

        <commanddef>
          <command><cmd>dom</cmd> <method>createDocument</method>

Changes to generic/dom.c.

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
61
62
63
64
65
66
67

68
69
70
71
72
73
74







-







|
\---------------------------------------------------------------------------*/
#ifdef DEBUG
# define DBG(x) x
#else
# define DBG(x) 
#endif
#define TDOM_NS

#define MutationEvent()
#define MutationEvent2(type,node)
#define MutationEvent3(type,node,relatioNode)

#define MCHK(a)  if ((a)==NULL) { \
                     fprintf(stderr, \
152
153
154
155
156
157
158

159
160
161
162
163
164
165
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165







+







    domDocument      *document;
    domNode          *currentNode;
    int               depth;
    int               ignoreWhiteSpaces;
    Tcl_DString      *cdata;
    TEncoding        *encoding_8bit;
    int               storeLineColumn;
    int               ignorexmlns;
    int               feedbackAfter;
    Tcl_Obj          *feedbackCmd;
    XML_Index         nextFeedbackPosition;
    Tcl_Interp       *interp;
    int               activeNSsize;
    int               activeNSpos;
    domActiveNS      *activeNS;
1190
1191
1192
1193
1194
1195
1196
1197
1198


1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226



























1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250























1251
1252

1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289








































1290
1291
1292
1293
1294
1295
1296
1297
1190
1191
1192
1193
1194
1195
1196


1197
1198
1199



























1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227























1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251

1252
1253




































1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293

1294
1295
1296
1297
1298
1299
1300







-
-
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-









    lastAttr = NULL;
    /*--------------------------------------------------------------
    |   process namespace declarations
    |
    \-------------------------------------------------------------*/
#ifdef TDOM_NS
    for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {
    if (!info->ignorexmlns) {
        for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {

        if (strncmp(atPtr[0], "xmlns", 5) == 0) {
            xmlns = atPtr[0];
            newNS = 1;
            if (xmlns[5] == ':') {
                if (domIsNamespaceInScope (info->activeNS, info->activeNSpos,
                                           &(xmlns[6]), atPtr[1])) {
                    ns = domLookupPrefix (info->currentNode, &(xmlns[6]));
                    newNS = 0;
                }
                else {
                    ns = domNewNamespace(info->document, &xmlns[6], atPtr[1]);
                }
            } else {
                ns = domNewNamespace(info->document, "", atPtr[1]);
            }
            if (newNS) {
                /* push active namespace */
                info->activeNSpos++;
                if (info->activeNSpos >= info->activeNSsize) {
                    info->activeNS = (domActiveNS*) REALLOC(
                        (char*)info->activeNS,
                        sizeof(domActiveNS) * 2 * info->activeNSsize);
                    info->activeNSsize = 2 * info->activeNSsize;
                }
                info->activeNS[info->activeNSpos].depth     = info->depth;
                info->activeNS[info->activeNSpos].namespace = ns;
            }
            if (strncmp(atPtr[0], "xmlns", 5) == 0) {
                xmlns = atPtr[0];
                newNS = 1;
                if (xmlns[5] == ':') {
                    if (domIsNamespaceInScope (info->activeNS, info->activeNSpos,
                                               &(xmlns[6]), atPtr[1])) {
                        ns = domLookupPrefix (info->currentNode, &(xmlns[6]));
                        newNS = 0;
                    }
                    else {
                        ns = domNewNamespace(info->document, &xmlns[6], atPtr[1]);
                    }
                } else {
                    ns = domNewNamespace(info->document, "", atPtr[1]);
                }
                if (newNS) {
                    /* push active namespace */
                    info->activeNSpos++;
                    if (info->activeNSpos >= info->activeNSsize) {
                        info->activeNS = (domActiveNS*) REALLOC(
                            (char*)info->activeNS,
                            sizeof(domActiveNS) * 2 * info->activeNSsize);
                        info->activeNSsize = 2 * info->activeNSsize;
                    }
                    info->activeNS[info->activeNSpos].depth     = info->depth;
                    info->activeNS[info->activeNSpos].namespace = ns;
                }

            h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
                                    atPtr[0], &hnew);
            attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
            memset(attrnode, 0, sizeof(domAttrNode));
            attrnode->nodeType    = ATTRIBUTE_NODE;
            attrnode->nodeFlags   = IS_NS_NODE;
            attrnode->namespace   = ns->index;
            attrnode->nodeName    = (char *)&(h->key);
            attrnode->parentNode  = node;
            len = strlen(atPtr[1]);
            if (TclOnly8Bits && info->encoding_8bit) {
                tdom_Utf8to8Bit(info->encoding_8bit, atPtr[1], &len);
            }
            attrnode->valueLength = len;
            attrnode->nodeValue   = (char*)MALLOC(len+1);
            strcpy(attrnode->nodeValue, atPtr[1]);
            if (node->firstAttr) {
                lastAttr->nextSibling = attrnode;
            } else {
                node->firstAttr = attrnode;
            }
            lastAttr = attrnode;
        }
                h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
                                        atPtr[0], &hnew);
                attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
                memset(attrnode, 0, sizeof(domAttrNode));
                attrnode->nodeType    = ATTRIBUTE_NODE;
                attrnode->nodeFlags   = IS_NS_NODE;
                attrnode->namespace   = ns->index;
                attrnode->nodeName    = (char *)&(h->key);
                attrnode->parentNode  = node;
                len = strlen(atPtr[1]);
                if (TclOnly8Bits && info->encoding_8bit) {
                    tdom_Utf8to8Bit(info->encoding_8bit, atPtr[1], &len);
                }
                attrnode->valueLength = len;
                attrnode->nodeValue   = (char*)MALLOC(len+1);
                strcpy(attrnode->nodeValue, atPtr[1]);
                if (node->firstAttr) {
                    lastAttr->nextSibling = attrnode;
                } else {
                    node->firstAttr = attrnode;
                }
                lastAttr = attrnode;
            }

    }
        }

    /*----------------------------------------------------------
    |   look for namespace of element
    \---------------------------------------------------------*/
    domSplitQName (name, tagPrefix, &localname);
    for (pos = info->activeNSpos; pos >= 0; pos--) {
        if (  ((tagPrefix[0] == '\0') && (info->activeNS[pos].namespace->prefix[0] == '\0'))
           || ((tagPrefix[0] != '\0') && (info->activeNS[pos].namespace->prefix[0] != '\0')
               && (strcmp(tagPrefix, info->activeNS[pos].namespace->prefix) == 0))
        ) {
            if (info->activeNS[pos].namespace->prefix[0] == '\0'
                && info->activeNS[pos].namespace->uri[0] == '\0'
                && tagPrefix[0] == '\0') {
                /* xml-names rec. 5.2: "The default namespace can be
                   set to the empty string. This has the same effect,
                   within the scope of the declaration, of there being
                   no default namespace." */
                goto elemNSfound;
            }
            node->namespace = info->activeNS[pos].namespace->index;
            DBG(fprintf(stderr, "tag='%s' uri='%s' \n",
                        node->nodeName,
                        info->activeNS[pos].namespace->uri);
            )
            goto elemNSfound;
        }
    }
    if (tagPrefix[0] != '\0') {
        if (strcmp (tagPrefix, "xml")==0) {
            node->namespace = info->document->rootNode->firstAttr->namespace;
        } else {
            /* Since where here, this means, the element has a
               up to now not declared namespace prefix. We probably
               should return this as an error, shouldn't we?*/
        }
    }
 elemNSfound:
        /*----------------------------------------------------------
          |   look for namespace of element
          \---------------------------------------------------------*/
        domSplitQName (name, tagPrefix, &localname);
        for (pos = info->activeNSpos; pos >= 0; pos--) {
            if (  ((tagPrefix[0] == '\0')
                   && (info->activeNS[pos].namespace->prefix[0] == '\0'))
                  || ((tagPrefix[0] != '\0') 
                      && (info->activeNS[pos].namespace->prefix[0] != '\0')
                      && (strcmp(tagPrefix, 
                                 info->activeNS[pos].namespace->prefix) == 0))
                ) {
                if (info->activeNS[pos].namespace->prefix[0] == '\0'
                    && info->activeNS[pos].namespace->uri[0] == '\0'
                    && tagPrefix[0] == '\0') {
                    /* xml-names rec. 5.2: "The default namespace can be
                       set to the empty string. This has the same effect,
                       within the scope of the declaration, of there being
                       no default namespace." */
                    goto elemNSfound;
                }
                node->namespace = info->activeNS[pos].namespace->index;
                DBG(fprintf(stderr, "tag='%s' uri='%s' \n",
                            node->nodeName,
                            info->activeNS[pos].namespace->uri);
                    )
                    goto elemNSfound;
            }
        }
        if (tagPrefix[0] != '\0') {
            if (strcmp (tagPrefix, "xml")==0) {
                node->namespace = info->document->rootNode->firstAttr->namespace;
            } else {
                /* Since where here, this means, the element has a
                   up to now not declared namespace prefix. We probably
                   should return this as an error, shouldn't we?*/
            }
        }
    }
elemNSfound:
#endif

    /*--------------------------------------------------------------
    |   add the attribute nodes
    |
    \-------------------------------------------------------------*/
    if ((idatt = XML_GetIdAttributeIndex (info->parser)) != -1) {
        if (!info->document->ids) {
1314
1315
1316
1317
1318
1319
1320
1321

1322
1323
1324
1325



1326

1327
1328
1329
1330
1331
1332
1333
1317
1318
1319
1320
1321
1322
1323

1324




1325
1326
1327

1328
1329
1330
1331
1332
1333
1334
1335







-
+
-
-
-
-
+
+
+
-
+







        idAttPtr = atts + idatt;
    } else {
        idAttPtr = NULL;
    }
    /* lastAttr already set right, either to NULL above, or to the last
       NS attribute */
    for (atPtr = atts; atPtr[0] && atPtr[1]; atPtr += 2) {

        if (!info->ignorexmlns) {
#ifdef TDOM_NS
        if (strncmp(atPtr[0], "xmlns", 5) == 0) {
            continue;
        }
            if (strncmp(atPtr[0], "xmlns", 5) == 0) {
                continue;
            }
#endif
        }
        h = Tcl_CreateHashEntry(&HASHTAB(info->document, tdom_attrNames),
                                atPtr[0], &hnew);
        attrnode = (domAttrNode*) domAlloc(sizeof(domAttrNode));
        memset(attrnode, 0, sizeof(domAttrNode));
        attrnode->nodeType = ATTRIBUTE_NODE;
        if (atPtr == idAttPtr) {
            attrnode->nodeFlags |= IS_ID_ATTRIBUTE;
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
































1385

1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412







1413

1414
1415
1416
1417
1418
1419
1420
1350
1351
1352
1353
1354
1355
1356






























1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388

1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409







1410
1411
1412
1413
1414
1415
1416

1417
1418
1419
1420
1421
1422
1423
1424







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+




















-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+







        if (node->firstAttr) {
            lastAttr->nextSibling = attrnode;
        } else {
            node->firstAttr = attrnode;
        }
        lastAttr = attrnode;

#ifdef TDOM_NS
        /*----------------------------------------------------------
        |   look for attribute namespace
        \---------------------------------------------------------*/
        domSplitQName (attrnode->nodeName, prefix, &localname);
        if (prefix[0] != '\0') {
            for (pos = info->activeNSpos; pos >= 0; pos--) {
                if (  ((prefix[0] == '\0') && (info->activeNS[pos].namespace->prefix[0] == '\0'))
                      || ((prefix[0] != '\0') && (info->activeNS[pos].namespace->prefix[0] != '\0')
                          && (strcmp(prefix, info->activeNS[pos].namespace->prefix) == 0))
                    ) {
                    attrnode->namespace = info->activeNS[pos].namespace->index;
                    DBG(fprintf(stderr, "attr='%s' uri='%s' \n",
                                attrnode->nodeName,
                                info->activeNS[pos].namespace->uri);
                        )
                    goto attrNSfound;
                }
            }
            if (strcmp (prefix, "xml")==0) {
                attrnode->namespace = 
                    info->document->rootNode->firstAttr->namespace;
            } else {
                /* Since where here, this means, the attribute has a
                   up to now not declared namespace prefix. We probably
                   should return this as an error, shouldn't we?*/
            }
        attrNSfound:
            ;
        }
        if (!info->ignorexmlns) {
            /*----------------------------------------------------------
              |   look for attribute namespace
              \---------------------------------------------------------*/
            domSplitQName (attrnode->nodeName, prefix, &localname);
            if (prefix[0] != '\0') {
                for (pos = info->activeNSpos; pos >= 0; pos--) {
                    if (  ((prefix[0] == '\0') 
                           && (info->activeNS[pos].namespace->prefix[0] == '\0'))
                          || ((prefix[0] != '\0') 
                              && (info->activeNS[pos].namespace->prefix[0] != '\0')
                              && (strcmp(prefix, info->activeNS[pos].namespace->prefix) == 0))
                        ) {
                        attrnode->namespace = info->activeNS[pos].namespace->index;
                        DBG(fprintf(stderr, "attr='%s' uri='%s' \n",
                                    attrnode->nodeName,
                                    info->activeNS[pos].namespace->uri);
                            )
                            goto attrNSfound;
                    }
                }
                if (strcmp (prefix, "xml")==0) {
                    attrnode->namespace = 
                        info->document->rootNode->firstAttr->namespace;
                } else {
                    /* Since where here, this means, the attribute has a
                       up to now not declared namespace prefix. We probably
                       should return this as an error, shouldn't we?*/
                }
            attrNSfound:
                ;
            }
#endif
        }
    }

    info->depth++;
}

/*---------------------------------------------------------------------------
|   endElement
|
\--------------------------------------------------------------------------*/
static void
endElement (
    void        *userData,
    const char  *name
)
{
    domReadInfo  *info = userData;

    DispatchPCDATA (info);
    
    info->depth--;
#ifdef TDOM_NS
    /* pop active namespaces */
    while ( (info->activeNSpos >= 0) &&
            (info->activeNS[info->activeNSpos].depth == info->depth) )
    {
        info->activeNSpos--;
    }
    if (!info->ignorexmlns) {
        /* pop active namespaces */
        while ( (info->activeNSpos >= 0) &&
                (info->activeNS[info->activeNSpos].depth == info->depth) )
        {
            info->activeNSpos--;
        }
#endif
    }

    if (info->depth != -1) {
        info->currentNode = info->currentNode->parentNode;
    } else {
        info->currentNode = NULL;
    }

2074
2075
2076
2077
2078
2079
2080

2081
2082
2083
2084
2085
2086
2087
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092







+







domReadDocument (
    XML_Parser  parser,
    char       *xml,
    int         length,
    int         ignoreWhiteSpaces,
    TEncoding  *encoding_8bit,
    int         storeLineColumn,
    int         ignorexmlns,
    int         feedbackAfter,
    Tcl_Obj    *feedbackCmd,
    Tcl_Channel channel,
    const char *baseurl,
    Tcl_Obj    *extResolver,
    int         useForeignDTD,
    int         paramEntityParsing,
2101
2102
2103
2104
2105
2106
2107



2108
2109
2110
2111
2112
2113
2114
2115
2116
2117

2118
2119
2120
2121
2122
2123
2124
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133







+
+
+










+







    char           *str;
#endif
    domDocument    *doc = domCreateDoc(baseurl, storeLineColumn);

    if (extResolver) {
        doc->extResolver = tdomstrdup (Tcl_GetString (extResolver));
    }
    if (ignorexmlns) {
        doc->nodeFlags |= IGNORE_XMLNS;
    }

    info.parser               = parser;
    info.document             = doc;
    info.currentNode          = NULL;
    info.depth                = 0;
    info.ignoreWhiteSpaces    = ignoreWhiteSpaces;
    info.cdata                = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
    Tcl_DStringInit (info.cdata);
    info.encoding_8bit        = encoding_8bit;
    info.storeLineColumn      = storeLineColumn;
    info.ignorexmlns          = ignorexmlns;
    info.feedbackAfter        = feedbackAfter;
    info.feedbackCmd          = feedbackCmd;
    info.nextFeedbackPosition = feedbackAfter;
    info.interp               = interp;
    info.activeNSpos          = -1;
    info.activeNSsize         = 8;
    info.activeNS             = (domActiveNS*) MALLOC (sizeof(domActiveNS) 
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2349
2350
2351
2352
2353
2354
2355

2356
2357
2358
2359
2360
2361
2362







-







        *column = lc->column;
        return 0;
    } else {
        return -1;
    }
}

#ifdef TDOM_NS
domAttrNode *
domCreateXMLNamespaceNode (
    domNode  *parent
)
{
    Tcl_HashEntry  *h;
    int             hnew;
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2373
2374
2375
2376
2377
2378
2379

2380
2381
2382
2383
2384
2385
2386







-







    attr->namespace     = ns->index;
    attr->nodeName      = (char *)&(h->key);
    attr->parentNode    = parent;
    attr->valueLength   = strlen (XML_NAMESPACE);
    attr->nodeValue     = tdomstrdup (XML_NAMESPACE);
    return attr;
}
#endif /* TDOM_NS */


/*
 *----------------------------------------------------------------------
 *
 * domCreateDoc --
 *
2390
2391
2392
2393
2394
2395
2396
2397

2398
2399
2400
2401
2402
2403
2404
2397
2398
2399
2400
2401
2402
2403

2404
2405
2406
2407
2408
2409
2410
2411







-
+







 *----------------------------------------------------------------------
 */

domDocument *
domCreateDoc (
    const char * baseURI,
    int          storeLineColumn
    )
)
{
    Tcl_HashEntry *h;
    int            hnew;
    domNode       *rootNode;
    domDocument   *doc;
    domLineColumn *lc;

2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2445
2446
2447
2448
2449
2450
2451

2452

2453
2454
2455
2456
2457
2458
2459







-

-







    rootNode->namespace     = 0;
    h = Tcl_CreateHashEntry(&HASHTAB(doc,tdom_tagNames), "", &hnew);
    rootNode->nodeName      = (char *)&(h->key);
    rootNode->nodeNumber    = NODE_NO(doc);
    rootNode->ownerDocument = doc;
    rootNode->parentNode    = NULL;
    rootNode->firstChild    = rootNode->lastChild = NULL;
#ifdef TDOM_NS
    rootNode->firstAttr     = domCreateXMLNamespaceNode (rootNode);
#endif
    if (storeLineColumn) {
        lc = (domLineColumn*) ( ((char*)rootNode) + sizeof(domNode));
        rootNode->nodeFlags |= HAS_LINE_COLUMN;
        lc->line            = 0;
        lc->column          = 0;
    }
    doc->rootNode = rootNode;
5158
5159
5160
5161
5162
5163
5164

5165
5166
5167
5168
5169
5170
5171
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177







+







    domDocument      *document;
    domNode          *currentNode;
    int               depth;
    int               ignoreWhiteSpaces;
    Tcl_DString      *cdata;
    TEncoding        *encoding_8bit;
    int               storeLineColumn;
    int               ignorexmlns;
    int               feedbackAfter;
    Tcl_Obj          *feedbackCmd;
    int               nextFeedbackPosition;
    Tcl_Interp       *interp;
    int               activeNSsize;
    int               activeNSpos;
    domActiveNS      *activeNS;
5235
5236
5237
5238
5239
5240
5241

5242
5243
5244
5245
5246
5247
5248
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255







+







        domFreeDocument (info->document, NULL, NULL);
    }

    info->document          = NULL;
    info->currentNode       = NULL;
    info->depth             = 0;
    info->feedbackAfter     = 0;
    info->ignorexmlns       = 0;
    Tcl_DStringSetLength (info->cdata, 0);
    info->nextFeedbackPosition = info->feedbackAfter;
    info->interp            = interp;
    info->activeNSpos       = -1;
    info->insideDTD         = 0;
    info->baseURIstackPos   = 0;
    info->tdomStatus        = 0;
5298
5299
5300
5301
5302
5303
5304
5305

5306
5307
5308
5309
5310
5311
5312

5313
5314
5315
5316
5317
5318
5319
5305
5306
5307
5308
5309
5310
5311

5312
5313
5314
5315
5316
5317
5318

5319
5320
5321
5322
5323
5324
5325
5326







-
+






-
+







    Tcl_Obj         *newObjName = NULL;
    TEncoding       *encoding;

    static CONST84 char *tdomMethods[] = {
        "enable", "getdoc",
        "setResultEncoding", "setStoreLineColumn",
        "setExternalEntityResolver", "keepEmpties",
        "remove",
        "remove", "ignorexmlns",
        NULL
    };
    enum tdomMethod {
        m_enable, m_getdoc,
        m_setResultEncoding, m_setStoreLineColumn,
        m_setExternalEntityResolver, m_keepEmpties,
        m_remove
        m_remove, m_ignorexmlns
    };

    if (objc < 3 || objc > 4) {
        Tcl_WrongNumArgs (interp, 1, objv, tdom_usage);
        return TCL_ERROR;
    }

5365
5366
5367
5368
5369
5370
5371

5372
5373
5374
5375
5376
5377
5378
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386







+







        info->currentNode       = NULL;
        info->depth             = 0;
        info->ignoreWhiteSpaces = 1;
        info->cdata             = (Tcl_DString*) MALLOC (sizeof (Tcl_DString));
        Tcl_DStringInit (info->cdata);
        info->encoding_8bit     = 0;
        info->storeLineColumn   = 0;
        info->ignorexmlns       = 0;
        info->feedbackAfter     = 0;
        info->feedbackCmd       = NULL;
        info->nextFeedbackPosition = 0;
        info->interp            = interp;
        info->activeNSpos       = -1;
        info->activeNSsize      = 8;
        info->activeNS          = 
5500
5501
5502
5503
5504
5505
5506
















5507
5508
5509
5510
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




        }
        Tcl_SetIntObj (Tcl_GetObjResult (interp), info->ignoreWhiteSpaces);
        Tcl_GetBooleanFromObj (interp, objv[3], &bool);
        info->ignoreWhiteSpaces = !bool;
        handlerSet->ignoreWhiteCDATAs = !bool;
        info->tdomStatus = 1;
        break;

    case m_ignorexmlns:
        info = CHandlerSetGetUserData (interp, objv[1], "tdom");
        if (!info) {
            Tcl_SetResult (interp, "parser object isn't tdom enabled.", NULL);
            return TCL_ERROR;
        }
        Tcl_SetIntObj (Tcl_GetObjResult (interp), info->ignorexmlns);
        if (objc == 4) {
            Tcl_GetBooleanFromObj (interp, objv[3], &bool);
            info->storeLineColumn = bool;
        }
        info->tdomStatus = 1;
        break;
        

    }

    return TCL_OK;
}

Changes to generic/dom.h.

435
436
437
438
439
440
441

442
443
444
445
446
447
448
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449







+







#define IS_NS_NODE                2

typedef unsigned int domDocFlags;

#define OUTPUT_DEFAULT_INDENT     1
#define NEEDS_RENUMBERING         2
#define DONT_FREE                 4
#define IGNORE_XMLNS              8

/*--------------------------------------------------------------------------
|   a index to the namespace records
|
\-------------------------------------------------------------------------*/
typedef unsigned int domNameSpaceIndex;

733
734
735
736
737
738
739

740
741
742
743
744
745
746
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748







+








domDocument *  domReadDocument   (XML_Parser parser,
                                  char *xml,
                                  int   length,
                                  int   ignoreWhiteSpaces,
                                  TEncoding *encoding_8bit,
                                  int   storeLineColumn,
                                  int   ignoreXMLNS,
                                  int   feedbackAfter,
                                  Tcl_Obj *feedbackCmd,
                                  Tcl_Channel channel,
                                  const char *baseurl,
                                  Tcl_Obj *extResolver,
                                  int   useForeignDTD,
                                  int   paramEntityParsing,

Changes to generic/domxslt.c.

5979
5980
5981
5982
5983
5984
5985
5986

5987
5988
5989
5990
5991
5992
5993
5979
5980
5981
5982
5983
5984
5985

5986
5987
5988
5989
5990
5991
5992
5993







-
+







    Tcl_ResetResult (interp);
    if (xsltDoc->extResolver) {
        extResolver = Tcl_NewStringObj(xsltDoc->extResolver, -1);
        Tcl_IncrRefCount (extResolver);
    }
    /* keep white space, no fiddling with the encoding (is this
       a good idea?) */
    doc = domReadDocument (parser, xmlstring, len, 0, 0, storeLineColumn, 0,
    doc = domReadDocument (parser, xmlstring, len, 0, 0, storeLineColumn, 0, 0,
                           NULL, chan, extbase, extResolver, 0, 
                           (int) XML_PARAM_ENTITY_PARSING_ALWAYS, interp,
                           &resultcode);
    if (xsltDoc->extResolver) {
        Tcl_DecrRefCount (extResolver);
    }
    if (doc == NULL) {

Changes to generic/tcldom.c.

1147
1148
1149
1150
1151
1152
1153

1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171



1172
1173
1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190







+


















+
+
+







+







    Tcl_Obj    *obj
)
{
    char        *xml_string;
    Tcl_Obj     *extResolver = NULL;
    int          xml_string_len;
    int          resultcode = 0;
    int          ignorexmlns = 0;
    domDocument *doc;
    domNode     *nodeToAppend;
    XML_Parser   parser;

    GetTcldomTSD()

    xml_string = Tcl_GetStringFromObj(obj, &xml_string_len);

#ifdef TDOM_NO_EXPAT
    SetResult("tDOM was compiled without Expat!");
    return TCL_ERROR;
#else
    parser = XML_ParserCreate_MM(NULL, MEM_SUITE, NULL);

    if (node->ownerDocument->extResolver) {
        extResolver = Tcl_NewStringObj(node->ownerDocument->extResolver, -1);
        Tcl_IncrRefCount (extResolver);
    }
    if (node->ownerDocument->nodeFlags & IGNORE_XMLNS) {
        ignorexmlns = 1;
    }

    doc = domReadDocument(parser,
                          xml_string,
                          xml_string_len,
                          1,
                          TSD(Encoding_to_8bit),
                          TSD(storeLineColumn),
                          ignorexmlns,
                          0,
                          NULL,
                          NULL,
                          NULL,
                          extResolver,
                          0,
                          (int) XML_PARAM_ENTITY_PARSING_ALWAYS,
5489
5490
5491
5492
5493
5494
5495

5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510

5511
5512
5513
5514
5515
5516
5517

5518
5519
5520
5521
5522
5523
5524
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515

5516
5517
5518
5519
5520
5521
5522

5523
5524
5525
5526
5527
5528
5529
5530







+














-
+






-
+







    Tcl_Obj     *feedbackCmd = NULL;
    CONST84 char *interpResult;
    int          optionIndex, value, xml_string_len, mode;
    int          ignoreWhiteSpaces   = 1;
    int          takeSimpleParser    = 0;
    int          takeHTMLParser      = 0;
    int          setVariable         = 0;
    int          ignorexmlns         = 0;
    int          feedbackAfter       = 0;
    int          useForeignDTD       = 0;
    int          paramEntityParsing  = (int)XML_PARAM_ENTITY_PARSING_ALWAYS;
    int          status              = 0;
    domDocument *doc;
    Tcl_Obj     *newObjName = NULL;
    XML_Parser   parser;
    Tcl_Channel  chan = (Tcl_Channel) NULL;
    Tcl_CmdInfo  cmdInfo;

    static CONST84 char *parseOptions[] = {
        "-keepEmpties",           "-simple",        "-html",
        "-feedbackAfter",         "-channel",       "-baseurl",
        "-externalentitycommand", "-useForeignDTD", "-paramentityparsing",
        "-feedbackcmd",
        "-feedbackcmd",           "-ignorexmlns",
        NULL
    };
    enum parseOption {
        o_keepEmpties,            o_simple,         o_html,
        o_feedbackAfter,          o_channel,        o_baseurl,
        o_externalentitycommand,  o_useForeignDTD,  o_paramentityparsing,
        o_feedbackcmd
        o_feedbackcmd,            o_ignorexmlns
    };

    static CONST84 char *paramEntityParsingValues[] = {
        "always",
        "never",
        "notstandalone",
        (char *) NULL
5670
5671
5672
5673
5674
5675
5676




5677
5678
5679
5680
5681
5682
5683
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693







+
+
+
+







            } else {
                SetResult("The \"dom parse\" option \"-feedbackcmd\" "
                          "requires a script as argument.");
                return TCL_ERROR;
            }
            objv++; objc--;
            continue;
            
        case o_ignorexmlns:
            ignorexmlns = 1;
            objv++;  objc--; continue;

        }
    }

    if (feedbackAfter && !feedbackCmd) {
        if (!Tcl_GetCommandInfo(interp, "::dom::domParseFeedback", 
                                &cmdInfo)) {
5770
5771
5772
5773
5774
5775
5776

5777
5778
5779
5780
5781
5782
5783
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794







+







    Tcl_ResetResult(interp);

    doc = domReadDocument(parser, xml_string,
                          xml_string_len,
                          ignoreWhiteSpaces,
                          TSD(Encoding_to_8bit),
                          TSD(storeLineColumn),
                          ignorexmlns,
                          feedbackAfter,
                          feedbackCmd,
                          chan,
                          baseURI,
                          extResolver,
                          useForeignDTD,
                          paramEntityParsing,

Changes to tests/dom.test.

455
456
457
458
459
460
461























462
463
464
465
466
467
468
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








test dom-2.26 {Not well-formed input} {
    catch {dom parse {<xsl:transform       
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform        
                   <http://www.w3.org/1999/XSL/Transform> "/>}}
} 1

test dom-2.27 {parse -ignorexmlns} {
    set result [list]
    set doc [dom parse {<doc xmlns="foo.bar"><child/></doc>}]
    set root [$doc documentElement]
    lappend result [$root localName]
    lappend result [$root namespaceURI]
    set child [$root firstChild]
    lappend result [$child localName]
    lappend result [$child namespaceURI]
    lappend result [$doc selectNodes count(/doc/child)]
    $doc delete
    set doc [dom parse -ignorexmlns {<doc xmlns="foo.bar"><child/></doc>}]
    set root [$doc documentElement]
    lappend result [$root nodeName]
    lappend result [$root namespaceURI]
    set child [$root firstChild]
    lappend result [$child nodeName]
    lappend result [$child namespaceURI]
    lappend result [$doc selectNodes count(/doc/child)]
    $doc delete
    set result
} {doc foo.bar child foo.bar 0 doc {} child {} 1}

test dom-3.1 {isName} {
    dom isName ":foo"
} {1}

test dom-3.2 {isName} {
    dom isName "_foo"
} {1}