Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 48da910

Browse files
author
Daniel Veillard
committed
allow to inherit attributes from the DTD directly in the tree, this is
* SAX.c testXPath.c valid.c xmllint.c include/libxml/valid.h: allow to inherit attributes from the DTD directly in the tree, this is needed for XPath and can be a useful feature. Inherited namespaces are always provided at the tree level now * test/defattr* result/defattr* result/noent/defattr*: added a couple of tests for this feature (XSLT being the prime user). Daniel
1 parent 50f3437 commit 48da910

File tree

12 files changed

+176
-7
lines changed

12 files changed

+176
-7
lines changed

Diff for: ChangeLog

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
Tue Aug 7 03:05:58 CEST 2001 Daniel Veillard <[email protected]>
2+
3+
* SAX.c testXPath.c valid.c xmllint.c include/libxml/valid.h:
4+
allow to inherit attributes from the DTD directly in the
5+
tree, this is needed for XPath and can be a useful feature.
6+
Inherited namespaces are always provided at the tree level now
7+
* test/defattr* result/defattr* result/noent/defattr*: added a couple
8+
of tests for this feature (XSLT being the prime user).
9+
110
Fri Aug 3 14:02:20 CEST 2001 Daniel Veillard <[email protected]>
211

312
* DOCBparser.c Makefile.am nanohttp.c parser.c testHTML.c

Diff for: SAX.c

+73
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <libxml/xmlIO.h>
2222
#include <libxml/SAX.h>
2323
#include <libxml/uri.h>
24+
#include <libxml/valid.h>
2425
#include <libxml/HTMLtree.h>
2526

2627
/* #define DEBUG_SAX */
@@ -1032,6 +1033,78 @@ startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
10321033
}
10331034
}
10341035

1036+
/*
1037+
* Insert all the defaulted attributes from the DTD especially namespaces
1038+
*/
1039+
if ((!ctxt->html) &&
1040+
((ctxt->myDoc->intSubset != NULL) ||
1041+
(ctxt->myDoc->extSubset != NULL))) {
1042+
xmlElementPtr elemDecl = NULL;
1043+
1044+
if (prefix != NULL) {
1045+
if (ctxt->myDoc->intSubset != NULL)
1046+
elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset,
1047+
name, prefix);
1048+
if ((elemDecl == NULL) && (ctxt->myDoc->extSubset != NULL))
1049+
elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
1050+
name, prefix);
1051+
} else {
1052+
if (ctxt->myDoc->intSubset != NULL)
1053+
elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset,
1054+
name, prefix);
1055+
if ((elemDecl == NULL) && (ctxt->myDoc->extSubset != NULL))
1056+
elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
1057+
name, prefix);
1058+
}
1059+
if (elemDecl != NULL) {
1060+
xmlAttributePtr attr = elemDecl->attributes;
1061+
while (attr != NULL) {
1062+
if (attr->defaultValue != NULL) {
1063+
/*
1064+
* the element should be instanciated in the tree if:
1065+
* - this is a namespace prefix
1066+
* - the user required for completion in the tree
1067+
* like XSLT
1068+
*/
1069+
if (((attr->prefix != NULL) &&
1070+
(xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
1071+
((attr->prefix == NULL) &&
1072+
(xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
1073+
(ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
1074+
xmlChar buffer[100];
1075+
const xmlChar *fulln = attr->name;
1076+
1077+
if (attr->prefix != NULL) {
1078+
snprintf((char *) buffer, 99, "%s:%s",
1079+
attr->prefix, attr->name);
1080+
buffer[99] = 0;
1081+
fulln = buffer;
1082+
}
1083+
1084+
/*
1085+
* Check that the attribute is not declared in the
1086+
* serialization
1087+
*/
1088+
att = NULL;
1089+
if (atts != NULL) {
1090+
i = 0;
1091+
att = atts[i];
1092+
while (att != NULL) {
1093+
if (xmlStrEqual(att, fulln))
1094+
break;
1095+
i += 2;
1096+
att = atts[i];
1097+
}
1098+
}
1099+
if (att == NULL)
1100+
attribute(ctxt, fulln, attr->defaultValue);
1101+
}
1102+
}
1103+
attr = attr->nexth;
1104+
}
1105+
}
1106+
}
1107+
10351108
/*
10361109
* process all the attributes whose name start with "xml"
10371110
*/

Diff for: include/libxml/valid.h

+7
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,15 @@ int xmlIsMixedElement (xmlDocPtr doc,
230230
xmlAttributePtr xmlGetDtdAttrDesc (xmlDtdPtr dtd,
231231
const xmlChar *elem,
232232
const xmlChar *name);
233+
xmlAttributePtr xmlGetDtdQAttrDesc (xmlDtdPtr dtd,
234+
const xmlChar *elem,
235+
const xmlChar *name,
236+
const xmlChar *prefix);
233237
xmlNotationPtr xmlGetDtdNotationDesc (xmlDtdPtr dtd,
234238
const xmlChar *name);
239+
xmlElementPtr xmlGetDtdQElementDesc (xmlDtdPtr dtd,
240+
const xmlChar *name,
241+
const xmlChar *prefix);
235242
xmlElementPtr xmlGetDtdElementDesc (xmlDtdPtr dtd,
236243
const xmlChar *name);
237244

Diff for: result/defattr.xml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE doc [
3+
<!ELEMENT doc EMPTY>
4+
<!ATTLIST doc xmlns CDATA #FIXED "http://www.example.com/">
5+
]>
6+
<doc xmlns="http://www.example.com/"/>

Diff for: result/defattr2.xml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE doc [
3+
<!ELEMENT doc EMPTY>
4+
<!ATTLIST doc defatt (0 | 1) "0">
5+
<!ATTLIST doc xmlns:tst CDATA #FIXED "http://example.org">
6+
<!ATTLIST doc tst:att (0 | 1) "1">
7+
]>
8+
<doc xmlns:tst="http://example.org" att="1"/>

Diff for: result/noent/defattr.xml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE doc [
3+
<!ELEMENT doc EMPTY>
4+
<!ATTLIST doc xmlns CDATA #FIXED "http://www.example.com/">
5+
]>
6+
<doc xmlns="http://www.example.com/"/>

Diff for: result/noent/defattr2.xml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE doc [
3+
<!ELEMENT doc EMPTY>
4+
<!ATTLIST doc defatt (0 | 1) "0">
5+
<!ATTLIST doc xmlns:tst CDATA #FIXED "http://example.org">
6+
<!ATTLIST doc tst:att (0 | 1) "1">
7+
]>
8+
<doc xmlns:tst="http://example.org" att="1"/>

Diff for: test/defattr.xml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<!DOCTYPE doc [
2+
<!ELEMENT doc EMPTY>
3+
<!ATTLIST doc
4+
xmlns CDATA #FIXED "http://www.example.com/">
5+
]>
6+
<doc/>

Diff for: test/defattr2.xml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!DOCTYPE doc [
2+
<!ELEMENT doc EMPTY>
3+
<!ATTLIST doc
4+
defatt (0|1) "0"
5+
xmlns:tst CDATA #FIXED "http://example.org"
6+
tst:att (0|1) "1">
7+
]>
8+
<doc att="1"/>

Diff for: testXPath.c

+2
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ int main(int argc, char **argv) {
175175
usefile++;
176176
}
177177
if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
178+
xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
179+
xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
178180
if (nocdata != 0) {
179181
xmlDefaultSAXHandlerInit();
180182
xmlDefaultSAXHandler.cdataBlock = NULL;

Diff for: valid.c

+31-4
Original file line numberDiff line numberDiff line change
@@ -1271,13 +1271,40 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
12711271
*/
12721272
elemDef = xmlGetDtdElementDesc2(dtd, elem, 1);
12731273
if (elemDef != NULL) {
1274+
12741275
if ((type == XML_ATTRIBUTE_ID) &&
12751276
(xmlScanIDAttributeDecl(NULL, elemDef) != 0))
12761277
VERROR(ctxt->userData,
12771278
"Element %s has too may ID attributes defined : %s\n",
12781279
elem, name);
1279-
ret->nexth = elemDef->attributes;
1280-
elemDef->attributes = ret;
1280+
/*
1281+
* Insert namespace default def first they need to be
1282+
* processed firt.
1283+
*/
1284+
if ((xmlStrEqual(ret->name, BAD_CAST "xmlns")) ||
1285+
((ret->prefix != NULL &&
1286+
(xmlStrEqual(ret->prefix, BAD_CAST "xmlns"))))) {
1287+
ret->nexth = elemDef->attributes;
1288+
elemDef->attributes = ret;
1289+
} else {
1290+
xmlAttributePtr tmp = elemDef->attributes;
1291+
1292+
while ((tmp != NULL) &&
1293+
((xmlStrEqual(tmp->name, BAD_CAST "xmlns")) ||
1294+
((ret->prefix != NULL &&
1295+
(xmlStrEqual(ret->prefix, BAD_CAST "xmlns")))))) {
1296+
if (tmp->nexth == NULL)
1297+
break;
1298+
tmp = tmp->nexth;
1299+
}
1300+
if (tmp != NULL) {
1301+
ret->nexth = tmp->nexth;
1302+
tmp->nexth = ret;
1303+
} else {
1304+
ret->nexth = elemDef->attributes;
1305+
elemDef->attributes = ret;
1306+
}
1307+
}
12811308
}
12821309

12831310
/*
@@ -2280,7 +2307,7 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
22802307
* returns the xmlElementPtr if found or NULL
22812308
*/
22822309

2283-
static xmlElementPtr
2310+
xmlElementPtr
22842311
xmlGetDtdQElementDesc(xmlDtdPtr dtd, const xmlChar *name,
22852312
const xmlChar *prefix) {
22862313
xmlElementTablePtr table;
@@ -2341,7 +2368,7 @@ xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) {
23412368
* returns the xmlAttributePtr if found or NULL
23422369
*/
23432370

2344-
static xmlAttributePtr
2371+
xmlAttributePtr
23452372
xmlGetDtdQAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name,
23462373
const xmlChar *prefix) {
23472374
xmlAttributeTablePtr table;

Diff for: xmllint.c

+12-3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ static char *encoding = NULL;
9797
#ifdef LIBXML_XINCLUDE_ENABLED
9898
static int xinclude = 0;
9999
#endif
100+
static int dtdattrs = 0;
100101
static int loaddtd = 0;
101102
static int progresult = 0;
102103
static int timing = 0;
@@ -792,8 +793,9 @@ static void usage(const char *name) {
792793
printf("\t--auto : generate a small doc on the fly\n");
793794
#ifdef LIBXML_XINCLUDE_ENABLED
794795
printf("\t--xinclude : do XInclude processing\n");
795-
printf("\t--loaddtd : fetch external Dtd\n");
796796
#endif
797+
printf("\t--loaddtd : fetch external Dtd\n");
798+
printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
797799
}
798800
int
799801
main(int argc, char **argv) {
@@ -850,7 +852,11 @@ main(int argc, char **argv) {
850852
else if ((!strcmp(argv[i], "-loaddtd")) ||
851853
(!strcmp(argv[i], "--loaddtd")))
852854
loaddtd++;
853-
else if ((!strcmp(argv[i], "-valid")) ||
855+
else if ((!strcmp(argv[i], "-dtdattr")) ||
856+
(!strcmp(argv[i], "--dtdattr"))) {
857+
loaddtd++;
858+
dtdattrs++;
859+
} else if ((!strcmp(argv[i], "-valid")) ||
854860
(!strcmp(argv[i], "--valid")))
855861
valid++;
856862
else if ((!strcmp(argv[i], "-postvalid")) ||
@@ -946,7 +952,10 @@ main(int argc, char **argv) {
946952
}
947953
}
948954
xmlLineNumbersDefault(1);
949-
if (loaddtd != 0) xmlLoadExtDtdDefaultValue = 6; /* fetch DTDs by default */
955+
if (loaddtd != 0)
956+
xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
957+
if (dtdattrs)
958+
xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
950959
if (noent != 0) xmlSubstituteEntitiesDefault(1);
951960
if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
952961
if ((htmlout) && (!nowrap)) {

0 commit comments

Comments
 (0)