Changed the internals a lot for DOM, entity support, slight changes of API,
more (if not all) formating of function comments, started documentation, Daniel.
diff --git a/ChangeLog b/ChangeLog
index d285e39..726f7f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Tue Oct 27 01:15:39 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
+
+ * parser.[ch] SAX.c tree.[ch]: large amount of changes to improve
+ entity support and provide an internal representation close to
+ DOM one (entity ref nodes, and attribute value as tree). I tried
+ to preserve the interface but this will surely break some apps
+ (I have to change rpm2html/rpmfind for example). I had to change
+ two interfaces, and the generated tree is somewhat different.
+ * doc/* : started documenting the XML library, the tree and
+ DOM/Corba. This is a first step.
+
Sat Oct 24 14:23:51 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
* parser.c: Set up the fonctions comment block, boring but useful.
diff --git a/SAX.c b/SAX.c
index 56585eb..9b7e504 100644
--- a/SAX.c
+++ b/SAX.c
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include "tree.h"
#include "parser.h"
+#include "entities.h"
#include "error.h"
/* #define DEBUG_SAX */
@@ -85,8 +86,11 @@
*
* Special entity resolver, better left to the parser, it has
* more context than the application layer.
+ * The default behaviour is to NOT resolve the entities, in that case
+ * the ENTITY_REF nodes are built in the structure (and the parameter
+ * values).
*
- * return values: an int
+ * return values: the xmlParserInputPtr if inlined or NULL for DOM behaviour.
*/
xmlParserInputPtr
resolveEntity(xmlParserCtxtPtr ctxt, const CHAR *publicId, const CHAR *systemId)
@@ -95,6 +99,7 @@
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
#endif
+
return(NULL);
}
@@ -206,16 +211,9 @@
void
startElement(xmlParserCtxtPtr ctxt, const CHAR *name)
{
- xmlNodePtr parent;
-
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.startElement(%s)\n", name);
#endif
- if (ctxt->nodeNr < 2) return;
- parent = ctxt->nodeTab[ctxt->nodeNr - 2];
- if (parent != NULL)
- xmlAddChild(parent, ctxt->node);
-
}
/**
@@ -254,7 +252,6 @@
#ifdef DEBUG_SAX
fprintf(stderr, "SAX.attribute(%s, %s)\n", name, value);
#endif
- xmlNewProp(ctxt->node, name, value);
}
/**
diff --git a/doc/DOM.fig b/doc/DOM.fig
new file mode 100644
index 0000000..7a48a32
--- /dev/null
+++ b/doc/DOM.fig
@@ -0,0 +1,64 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 825 1125 2625 1125 2625 3375 825 3375 825 1125
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 4125 1125 5925 1125 5925 3375 4125 3375 4125 1125
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 2025 3075 2025 1650 1050 1650 1050 3075 2025 3075
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 1425 1875 1575 1875 1575 2025 1425 2025 1425 1875
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 1200 2175 1350 2175 1350 2325 1200 2325 1200 2175
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 1500 2175 1650 2175 1650 2325 1500 2325 1500 2175
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 1800 2175 1950 2175 1950 2325 1800 2325 1800 2175
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 1500 2475 1650 2475 1650 2625 1500 2625 1500 2475
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 1725 2700 1875 2700 1875 2850 1725 2850 1725 2700
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 1275 2700 1425 2700 1425 2850 1275 2850 1275 2700
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1500 2025 1350 2175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1500 2025 1575 2175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1500 2025 1875 2175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1575 2325 1575 2475
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1650 2625 1725 2700
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1500 2625 1425 2700
+2 3 0 2 0 7 0 0 -1 6.000 0 0 -1 0 0 5
+ 2550 1725 2175 1950 2175 2850 2550 3075 2550 1725
+2 3 0 2 0 7 0 0 -1 6.000 0 0 -1 0 0 5
+ 4575 1725 4200 1950 4200 2850 4575 3075 4575 1725
+2 2 0 1 0 7 0 0 -1 4.000 0 0 -1 0 0 5
+ 2700 2025 4050 2025 4050 2775 2700 2775 2700 2025
+2 1 0 2 0 7 0 0 -1 6.000 0 0 -1 0 0 2
+ 5025 2025 4575 2175
+2 1 1 2 0 7 0 0 -1 6.000 0 0 -1 1 0 3
+ 1 1 2.00 120.00 240.00
+ 4575 2175 4200 2250 2025 2250
+2 1 1 2 0 7 0 0 -1 6.000 0 0 -1 0 0 3
+ 2025 2475 4200 2475 4575 2550
+2 1 0 2 0 7 0 0 -1 6.000 0 0 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 4575 2550 5025 2625
+4 0 0 0 0 0 18 0.0000 4 255 1155 1050 825 Program 1\001
+4 0 0 0 0 0 18 0.0000 4 255 1155 4425 900 Program 2\001
+4 0 0 0 0 0 18 0.0000 4 195 585 1350 1500 XML\001
+4 0 0 0 0 0 18 0.0000 4 195 975 3000 3075 CORBA\001
+4 0 0 0 0 0 18 0.0000 4 195 735 3000 3375 ORBit\001
+4 0 0 0 0 0 18 0.0000 4 195 1395 2175 1575 DOM server\001
+4 0 0 0 0 0 18 0.0000 4 195 1335 4200 1650 DOM client\001
diff --git a/doc/DOM.gif b/doc/DOM.gif
new file mode 100644
index 0000000..a44882f
--- /dev/null
+++ b/doc/DOM.gif
Binary files differ
diff --git a/doc/structure.fig b/doc/structure.fig
new file mode 100644
index 0000000..34f6237
--- /dev/null
+++ b/doc/structure.fig
@@ -0,0 +1,303 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+6 1275 4425 5475 5100
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 2250 5100 2250 4425 1275 4425 1275 5100 2250 5100
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 3975 5100 3975 4425 3000 4425 3000 5100 3975 5100
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 5475 5100 5475 4425 4500 4425 4500 5100 5475 5100
+4 0 0 0 0 14 16 0.0000 4 135 600 4650 4725 TEXT\001
+4 0 0 0 0 14 16 0.0000 4 135 600 1425 4725 TEXT\001
+4 0 0 0 0 14 16 0.0000 4 135 900 3075 4725 ENTITY\001
+4 0 0 0 0 14 16 0.0000 4 135 450 3075 4950 REF\001
+-6
+6 825 4575 900 5100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 4575 900 5100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 5025 825 5100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 4950 825 5025
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 4800 825 4875
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 4875 825 4950
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 4650 825 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 4725 825 4800
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 4575 825 4650
+-6
+6 1125 2325 1200 2850
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1200 2325 1200 2850
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1200 2775 1125 2850
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1200 2700 1125 2775
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1200 2550 1125 2625
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1200 2625 1125 2700
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1200 2400 1125 2475
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1200 2475 1125 2550
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1200 2325 1125 2400
+-6
+6 2550 4650 2625 5175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 4650 2625 5175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 5100 2550 5175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 5025 2550 5100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 4875 2550 4950
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 4950 2550 5025
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 4725 2550 4800
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 4800 2550 4875
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 4650 2550 4725
+-6
+6 6000 4200 6075 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 6075 4200 6075 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 6075 4650 6000 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 6075 4575 6000 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 6075 4425 6000 4500
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 6075 4500 6000 4575
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 6075 4275 6000 4350
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 6075 4350 6000 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 6075 4200 6000 4275
+-6
+6 2475 4425 2550 4950
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 4950 2475 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 4500 2550 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 4575 2550 4500
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 4725 2550 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 4650 2550 4575
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 4875 2550 4800
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 4800 2550 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 4950 2550 4875
+-6
+6 5775 4425 5850 4950
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 5775 4950 5775 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 5775 4500 5850 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 5775 4575 5850 4500
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 5775 4725 5850 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 5775 4650 5850 4575
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 5775 4875 5850 4800
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 5775 4800 5850 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 5775 4950 5850 4875
+-6
+6 9000 2100 9075 2625
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 9000 2625 9000 2100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 9000 2175 9075 2100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 9000 2250 9075 2175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 9000 2400 9075 2325
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 9000 2325 9075 2250
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 9000 2550 9075 2475
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 9000 2475 9075 2400
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 9000 2625 9075 2550
+-6
+6 11850 4050 11925 4575
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 11850 4575 11850 4050
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 11850 4125 11925 4050
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 11850 4200 11925 4125
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 11850 4350 11925 4275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 11850 4275 11925 4200
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 11850 4500 11925 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 11850 4425 11925 4350
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 11850 4575 11925 4500
+-6
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 3150 375 4425 375 4425 1275 3150 1275 3150 375
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 2850 2775 2850 2100 1875 2100 1875 2775 2850 2775
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 5550 2775 5550 2100 4575 2100 4575 2775 5550 2775
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 8175 2775 8175 2100 7200 2100 7200 2775 8175 2775
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 7650 4725 7650 4050 6675 4050 6675 4725 7650 4725
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 9675 4725 9675 4050 8700 4050 8700 4725 9675 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3750 1275 2400 2100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2850 2325 4575 2325
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 5550 2325 7200 2325
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 8175 2325 9000 2325
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7200 2550 5550 2550
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4575 2550 2850 2550
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1875 2550 1200 2550
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2250 2100 3525 1275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 5100 2100 4050 1275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7725 2100 4125 1275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7725 2775 7125 4050
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7650 4275 8700 4275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 8700 4425 7650 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 9675 4275 10275 4275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6675 4500 6075 4500
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 1275 3375 2250 3375 2250 3825 1275 3825 1275 3375
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 3000 3375 3975 3375 3975 3825 3000 3825 3000 3375
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2325 2775 1725 3375
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2250 3600 3000 3600
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+ 11250 4725 11250 4050 10275 4050 10275 4725 11250 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 11250 4275 11850 4275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10275 4425 9675 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1725 3825 1725 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3450 3825 3450 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3975 4650 4500 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 5475 4650 5775 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4500 4875 3975 4875
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2250 4650 2550 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1275 4875 900 4875
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 975 5625 2550 5625 2550 5850 975 5850 975 5625
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 4200 5625 5775 5625 5775 5850 4200 5850 4200 5625
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 6450 5250 8025 5250 8025 5475 6450 5475 6450 5250
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 10125 5250 11700 5250 11700 5475 10125 5475 10125 5250
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1725 5100 1725 5625
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4875 5100 4875 5625
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7050 4725 7050 5250
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 10650 4725 10650 5250
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3000 4875 2625 4875
+4 0 0 0 0 0 16 0.0000 4 150 420 3000 2250 next\001
+4 0 0 0 0 0 16 0.0000 4 180 450 3975 2775 prev\001
+4 0 0 0 0 0 16 0.0000 4 210 630 5100 2025 parent\001
+4 0 0 0 0 14 15 0.0000 4 135 945 7200 2475 ELEMENT\001
+4 0 0 0 0 14 15 0.0000 4 135 945 4575 2475 ELEMENT\001
+4 0 0 0 0 14 15 0.0000 4 135 945 1875 2475 ELEMENT\001
+4 0 0 0 0 14 16 0.0000 4 135 450 8775 4590 REF\001
+4 0 0 0 0 14 16 0.0000 4 135 900 8775 4350 ENTITY\001
+4 0 0 0 0 14 16 0.0000 4 135 600 10350 4425 TEXT\001
+4 0 0 0 0 14 16 0.0000 4 135 600 6750 4425 TEXT\001
+4 0 0 0 0 14 16 0.0000 4 150 1050 1275 2025 xmlNode\001
+4 0 0 0 0 14 16 0.0000 4 150 900 2175 675 xmlDoc\001
+4 0 0 0 0 14 16 0.0000 4 150 1050 675 3300 xmlAttr\001
+4 0 0 0 0 14 16 0.0000 4 135 1200 3225 825 DOCUMENT\001
+4 0 0 0 0 0 16 0.0000 4 150 390 3375 1650 root\001
+4 0 0 0 0 -1 20 0.0000 4 285 4770 5175 825 A DOM tree as built by the XML parser\001
+4 0 0 0 0 -1 20 0.0000 4 180 465 1050 6150 text\001
+4 0 0 0 0 -1 16 0.0000 4 225 990 2250 3000 properties\001
+4 0 0 0 0 -1 16 0.0000 4 150 720 1800 5475 content\001
diff --git a/doc/structure.gif b/doc/structure.gif
new file mode 100644
index 0000000..6711480
--- /dev/null
+++ b/doc/structure.gif
Binary files differ
diff --git a/doc/xml.html b/doc/xml.html
new file mode 100644
index 0000000..d0f57a4
--- /dev/null
+++ b/doc/xml.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+ "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+<head>
+<title>No title</title>
+<meta name="GENERATOR" content="amaya V1.3b">
+</head>
+<body bgcolor="#ffffff">
+
+<h1 align="center">The XML library for Gnome</h1>
+<p>
+This document describes the <a href="http://www.w3.org/XML/">XML</a> library
+provideed in the <a href="http://www.gnome.org/">Gnome</a> framework. XML is a
+standard to build tag based structured documents. The internal document
+repesentation is as close as possible to the <a
+href="http://www.w3.org/DOM/">DOM</a> interfaces.</p>
+
+<h2>xml</h2>
+<p>
+XML is a standard for markup based structured documents, here is an
+example:</p>
+<pre><?xml version="1.0"?>
+<EXAMPLE prop1="gnome is great" prop2="&linux; too">
+ <head>
+ <title>Welcome to Gnome</title>
+ </head>
+ <chapter>
+ <title>The Linux adventure</title>
+ <p>bla bla bla ...</p>
+ <image href="linus.gif"/>
+ <p>...</p>
+ </chapter>
+</EXAMPLE></pre>
+<p>
+ </p>
+
+<h2>Invoking the parser</h2>
+
+<h2>The tree output</h2>
+<p>
+The parser returns a tree built during the document analysis. The value
+returned is an <strong>xmlDocPtr</strong> (i.e. a pointer to an
+<strong>xmlDoc</strong> structure). This structure contains informations like
+the file name, the document type, and a <strong>root</strong> pointer which
+is the root of the document (or more exactly the first child under the root
+which is the document). The tree is made of <strong>xmlNode</strong>s, chained
+in double linked lists of siblings and with childs<->parent relationship.
+An xmlNode can also carry properties (a chain of xmlAttr structures). An
+attribute may have a value which is a list of TEXT or ENTITY_REF nodes.</p>
+<p>
+Here is an example (erroneous w.r.t. the XML spec since there should be only
+one ELEMENT under the root):</p>
+<p>
+<img src="structure.gif" alt=" structure.gif "></p>
+<p>
+</p>
+
+<h2>Modifying the tree</h2>
+
+<h2>Saving a tree</h2>
+
+<h2>DOM interfaces</h2>
+<p>
+<a href="http://www.w3.org/DOM/">DOM</a> stands for the <em>Document Object
+Model</em> this is an API for accessing XML or HTML structured documents.
+Native support for DOM in Gnome is on the way (module gnome-dom), and it will
+be based on gnome-xml. DOM defiles a set of IDL (or Java) interfaces allowing
+to traverse and manipulate a document. The DOM library will allow accessing
+and modifying "live" documents presents on other programs like this:</p>
+<p>
+<img src="DOM.gif" alt=" DOM.gif "></p>
+<p>
+This should help greatly doing things like modifying a gnumeric spreadsheet
+embedded in a GWP document for example.</p>
+<p>
+</p>
+</body>
+</html>
diff --git a/encoding.c b/encoding.c
index 02ff02a..7753419 100644
--- a/encoding.c
+++ b/encoding.c
@@ -77,7 +77,7 @@
unsigned char* outstart= out;
unsigned char* outend= out+outlen;
unsigned char* inend= in+inlen;
- unsigned char c, d;
+ unsigned char c;
while (in < inend) {
c= *in++;
diff --git a/entities.c b/entities.c
index 5a788e6..351746c 100644
--- a/entities.c
+++ b/entities.c
@@ -143,6 +143,29 @@
}
}
+/**
+ * xmlGetPredefinedEntity:
+ * @name: the entity name
+ *
+ * Check whether this name is an predefined entity.
+ *
+ * return values: NULL if not, othervise the entity
+ */
+xmlEntityPtr
+xmlGetPredefinedEntity(const CHAR *name) {
+ int i;
+ xmlEntityPtr cur;
+
+ if (xmlPredefinedEntities == NULL)
+ xmlInitializePredefinedEntities();
+ for (i = 0;i < xmlPredefinedEntities->nb_entities;i++) {
+ cur = &xmlPredefinedEntities->table[i];
+ if (!xmlStrcmp(cur->name, name)) return(cur);
+ }
+ return(NULL);
+}
+
+
/*
* xmlAddDtdEntity : register a new entity for this DTD.
diff --git a/entities.h b/entities.h
index 0065245..6f971c0 100644
--- a/entities.h
+++ b/entities.h
@@ -8,8 +8,8 @@
#ifndef __XML_ENTITIES_H__
#define __XML_ENTITIES_H__
-#include "parser.h"
+#include "parser.h"
#ifdef __cplusplus
extern "C" {
@@ -48,6 +48,7 @@
xmlEntityPtr table; /* the table of entities */
} xmlEntitiesTable, *xmlEntitiesTablePtr;
+
/*
* External functions :
*/
@@ -56,12 +57,15 @@
const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
extern void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern xmlEntityPtr xmlGetPredefinedEntity(const CHAR *name);
extern xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name);
extern xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name);
extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
extern void xmlDumpEntitiesTable(xmlEntitiesTablePtr table);
+extern xmlParserInputPtr xmlNewEntityInputStream(xmlParserCtxtPtr ctxt,
+ xmlEntityPtr entity);
#ifdef __cplusplus
}
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
index 0065245..6f971c0 100644
--- a/include/libxml/entities.h
+++ b/include/libxml/entities.h
@@ -8,8 +8,8 @@
#ifndef __XML_ENTITIES_H__
#define __XML_ENTITIES_H__
-#include "parser.h"
+#include "parser.h"
#ifdef __cplusplus
extern "C" {
@@ -48,6 +48,7 @@
xmlEntityPtr table; /* the table of entities */
} xmlEntitiesTable, *xmlEntitiesTablePtr;
+
/*
* External functions :
*/
@@ -56,12 +57,15 @@
const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
extern void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern xmlEntityPtr xmlGetPredefinedEntity(const CHAR *name);
extern xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name);
extern xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name);
extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
extern void xmlDumpEntitiesTable(xmlEntitiesTablePtr table);
+extern xmlParserInputPtr xmlNewEntityInputStream(xmlParserCtxtPtr ctxt,
+ xmlEntityPtr entity);
#ifdef __cplusplus
}
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index d0ca958..51ba467 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -128,6 +128,8 @@
extern xmlSAXLocator xmlDefaultSAXLocator;
extern xmlSAXHandler xmlDefaultSAXHandler;
+#include "entities.h"
+
/*
* Interfaces
*/
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index 91677a6..2ebe2cd 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -16,7 +16,30 @@
#endif
/*
- * Type definitions
+ * The different element types carried by an XML tree
+ *
+ * NOTE: This is synchronized with DOM Level1 values
+ * See http://www.w3.org/TR/REC-DOM-Level-1/
+ */
+typedef enum {
+ XML_ELEMENT_NODE= 1,
+ XML_ATTRIBUTE_NODE= 2,
+ XML_TEXT_NODE= 3,
+ XML_CDATA_SECTION_NODE= 4,
+ XML_ENTITY_REF_NODE= 5,
+ XML_ENTITY_NODE= 6,
+ XML_PI_NODE= 7,
+ XML_COMMENT_NODE= 8,
+ XML_DOCUMENT_NODE= 9,
+ XML_DOCUMENT_TYPE_NODE= 10,
+ XML_DOCUMENT_FRAG_NODE= 11,
+ XML_NOTATION_NODE= 12
+} xmlElementType;
+
+/*
+ * Currently we use only 8bit chars internal representation, but
+ * the parser is not tied to that, just define UNICODE to switch to
+ * a 16 bits representation.
*/
#ifdef UNICODE
typedef unsigned short CHAR;
@@ -84,37 +107,22 @@
void *_private; /* for Corba, must be first ! */
void *vepv; /* for Corba, must be next ! */
#endif
- int type; /* XML_ATTRIBUTE_NODE, must be third ! */
+ xmlElementType type; /* XML_ATTRIBUTE_NODE, must be third ! */
struct xmlNode *node; /* attr->node link */
struct xmlAttr *next; /* parent->childs link */
const CHAR *name; /* the name of the property */
- const CHAR *value; /* the value of the property */
+ struct xmlNode *val; /* the value of the property */
} xmlAttr, *xmlAttrPtr;
/*
* A node in an XML tree.
- * NOTE: This is synchronized with DOM Level1 values
- * See http://www.w3.org/TR/REC-DOM-Level-1/
*/
-#define XML_ELEMENT_NODE 1
-#define XML_ATTRIBUTE_NODE 2
-#define XML_TEXT_NODE 3
-#define XML_CDATA_SECTION_NODE 4
-#define XML_ENTITY_REF_NODE 5
-#define XML_ENTITY_NODE 6
-#define XML_PI_NODE 7
-#define XML_COMMENT_NODE 8
-#define XML_DOCUMENT_NODE 9
-#define XML_DOCUMENT_TYPE_NODE 10
-#define XML_DOCUMENT_FRAG_NODE 11
-#define XML_NOTATION_NODE 12
-
typedef struct xmlNode {
#ifndef XML_WITHOUT_CORBA
void *_private; /* for Corba, must be first ! */
void *vepv; /* for Corba, must be next ! */
#endif
- int type; /* type number in the DTD, must be third ! */
+ xmlElementType type; /* type number in the DTD, must be third ! */
struct xmlDoc *doc; /* the containing document */
struct xmlNode *parent; /* child->parent link */
struct xmlNode *next; /* next sibling link */
@@ -135,7 +143,7 @@
void *_private; /* for Corba, must be first ! */
void *vepv; /* for Corba, must be next ! */
#endif
- int type; /* XML_DOCUMENT_NODE, must be second ! */
+ xmlElementType type; /* XML_DOCUMENT_NODE, must be second ! */
char *name; /* name/filename/URI of the document */
const CHAR *version; /* the XML version string */
const CHAR *encoding; /* encoding, if any */
@@ -165,22 +173,27 @@
extern void xmlFreeNs(xmlNsPtr cur);
extern xmlDocPtr xmlNewDoc(const CHAR *version);
extern void xmlFreeDoc(xmlDocPtr cur);
+extern xmlAttrPtr xmlNewDocProp(xmlDocPtr doc, const CHAR *name,
+ const CHAR *value);
extern xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
const CHAR *value);
extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
const CHAR *value);
extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
+extern xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value);
+extern CHAR *xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine);
extern void xmlFreePropList(xmlAttrPtr cur);
extern void xmlFreeProp(xmlAttrPtr cur);
extern xmlNodePtr xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
const CHAR *name, CHAR *content);
-extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content);
+extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name);
extern xmlNodePtr xmlNewDocText(xmlDocPtr doc, const CHAR *content);
extern xmlNodePtr xmlNewText(const CHAR *content);
extern xmlNodePtr xmlNewDocTextLen(xmlDocPtr doc, const CHAR *content, int len);
extern xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
extern xmlNodePtr xmlNewDocComment(xmlDocPtr doc, CHAR *content);
extern xmlNodePtr xmlNewComment(CHAR *content);
+extern xmlNodePtr xmlNewReference(xmlDocPtr doc, const CHAR *name);
extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
extern xmlNodePtr xmlGetLastChild(xmlNodePtr node);
extern int xmlNodeIsText(xmlNodePtr node);
diff --git a/parser.c b/parser.c
index 299a09a..47323e0 100644
--- a/parser.c
+++ b/parser.c
@@ -58,7 +58,10 @@
type name##Pop(xmlParserCtxtPtr ctxt) { \
if (ctxt->name##Nr <= 0) return(0); \
ctxt->name##Nr--; \
- ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
+ if (ctxt->name##Nr > 0) \
+ ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1]; \
+ else \
+ ctxt->name = NULL; \
return(ctxt->name); \
} \
@@ -123,31 +126,33 @@
* @entity: an Entity pointer
*
* Create a new input stream based on a memory buffer.
+ * return vakues: the new input stream
*/
-void xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+xmlParserInputPtr
+xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
xmlParserInputPtr input;
if (entity == NULL) {
xmlParserError(ctxt,
"internal: xmlNewEntityInputStream entity = NULL\n");
- return;
+ return(NULL);
}
if (entity->content == NULL) {
xmlParserError(ctxt,
"internal: xmlNewEntityInputStream entity->input = NULL\n");
- return;
+ return(NULL);
}
input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
if (input == NULL) {
xmlParserError(ctxt, "malloc: couldn't allocate a new input stream\n");
- return;
+ return(NULL);
}
input->filename = entity->SystemID; /* TODO !!! char <- CHAR */
input->base = entity->content;
input->cur = entity->content;
input->line = 1;
input->col = 1;
- xmlPushInput(ctxt, input);
+ return(input);
}
/*
@@ -876,6 +881,7 @@
void xmlHandleEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
int len;
+ xmlParserInputPtr input;
if (entity->content == NULL) {
xmlParserError(ctxt, "xmlHandleEntity %s: content == NULL\n",
@@ -888,7 +894,8 @@
/*
* Redefine its content as an input stream.
*/
- xmlNewEntityInputStream(ctxt, entity);
+ input = xmlNewEntityInputStream(ctxt, entity);
+ xmlPushInput(ctxt, input);
return;
handle_as_char:
@@ -904,8 +911,8 @@
* Forward definition for recusive behaviour.
*/
xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt);
-CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt, int inLine);
-CHAR *xmlParseReference(xmlParserCtxtPtr ctxt, int inLine);
+CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt);
+CHAR *xmlParseReference(xmlParserCtxtPtr ctxt);
/************************************************************************
* *
@@ -1231,13 +1238,22 @@
while ((IS_CHAR(CUR)) && (CUR != '"')) {
if (CUR == '%') {
ret = xmlStrncat(ret, q, CUR_PTR - q);
- cur = xmlParsePEReference(ctxt, 1);
+ cur = xmlParsePEReference(ctxt);
ret = xmlStrcat(ret, cur);
q = CUR_PTR;
} else if (CUR == '&') {
ret = xmlStrncat(ret, q, CUR_PTR - q);
- cur = xmlParseReference(ctxt, 1);
- ret = xmlStrcat(ret, cur);
+ cur = xmlParseReference(ctxt);
+ if (cur != NULL) {
+ CHAR buf[2];
+ buf[0] = '&';
+ buf[1] = 0;
+ ret = xmlStrncat(ret, buf, 1);
+ ret = xmlStrcat(ret, cur);
+ buf[0] = ';';
+ buf[1] = 0;
+ ret = xmlStrncat(ret, buf, 1);
+ }
q = CUR_PTR;
} else
NEXT;
@@ -1254,13 +1270,22 @@
while ((IS_CHAR(CUR)) && (CUR != '\'')) {
if (CUR == '%') {
ret = xmlStrncat(ret, q, CUR_PTR - q);
- cur = xmlParsePEReference(ctxt, 1);
+ cur = xmlParsePEReference(ctxt);
ret = xmlStrcat(ret, cur);
q = CUR_PTR;
} else if (CUR == '&') {
ret = xmlStrncat(ret, q, CUR_PTR - q);
- cur = xmlParseReference(ctxt, 1);
- ret = xmlStrcat(ret, cur);
+ cur = xmlParseReference(ctxt);
+ if (cur != NULL) {
+ CHAR buf[2];
+ buf[0] = '&';
+ buf[1] = 0;
+ ret = xmlStrncat(ret, buf, 1);
+ ret = xmlStrcat(ret, cur);
+ buf[0] = ';';
+ buf[1] = 0;
+ ret = xmlStrncat(ret, buf, 1);
+ }
q = CUR_PTR;
} else
NEXT;
@@ -1300,11 +1325,32 @@
while ((IS_CHAR(CUR)) && (CUR != '"')) {
if (CUR == '&') {
ret = xmlStrncat(ret, q, CUR_PTR - q);
- cur = xmlParseReference(ctxt, 1);
- ret = xmlStrcat(ret, cur);
+ cur = xmlParseReference(ctxt);
+ if (cur != NULL) {
+ /*
+ * Special case for '&', we don't want to
+ * resolve it here since it will break later
+ * when searching entities in the string.
+ */
+ if ((cur[0] == '&') && (cur[1] == 0)) {
+ CHAR buf[6] = { '&', 'a', 'm', 'p', ';', 0 };
+ ret = xmlStrncat(ret, buf, 5);
+ } else
+ ret = xmlStrcat(ret, cur);
+ free(cur);
+ }
q = CUR_PTR;
} else
NEXT;
+ /*
+ * Pop out finished entity references.
+ */
+ while ((CUR == 0) && (ctxt->inputNr > 1)) {
+ if (CUR_PTR != q)
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ xmlPopInput(ctxt);
+ q = CUR_PTR;
+ }
}
if (!IS_CHAR(CUR)) {
xmlParserError(ctxt, "Unfinished AttValue\n");
@@ -1318,11 +1364,32 @@
while ((IS_CHAR(CUR)) && (CUR != '\'')) {
if (CUR == '&') {
ret = xmlStrncat(ret, q, CUR_PTR - q);
- cur = xmlParseReference(ctxt, 1);
- ret = xmlStrcat(ret, cur);
+ cur = xmlParseReference(ctxt);
+ if (cur != NULL) {
+ /*
+ * Special case for '&', we don't want to
+ * resolve it here since it will break later
+ * when searching entities in the string.
+ */
+ if ((cur[0] == '&') && (cur[1] == 0)) {
+ CHAR buf[6] = { '&', 'a', 'm', 'p', ';', 0 };
+ ret = xmlStrncat(ret, buf, 5);
+ } else
+ ret = xmlStrcat(ret, cur);
+ free(cur);
+ }
q = CUR_PTR;
} else
NEXT;
+ /*
+ * Pop out finished entity references.
+ */
+ while ((CUR == 0) && (ctxt->inputNr > 1)) {
+ if (CUR_PTR != q)
+ ret = xmlStrncat(ret, q, CUR_PTR - q);
+ xmlPopInput(ctxt);
+ q = CUR_PTR;
+ }
}
if (!IS_CHAR(CUR)) {
xmlParserError(ctxt, "Unfinished AttValue\n");
@@ -2060,7 +2127,6 @@
/**
* xmlParseCharRef:
* @ctxt: an XML parser context
- * @inLine: handle it as inline or pass it to SAX as chars ?
*
* parse Reference declarations
*
@@ -2068,7 +2134,7 @@
* '&#x' [0-9a-fA-F]+ ';'
* return values: the value parsed
*/
-CHAR *xmlParseCharRef(xmlParserCtxtPtr ctxt, int inLine) {
+CHAR *xmlParseCharRef(xmlParserCtxtPtr ctxt) {
int val = 0;
CHAR buf[2];
@@ -2114,10 +2180,7 @@
if (IS_CHAR(val)) {
buf[0] = (CHAR) val;
buf[1] = 0;
- if (inLine)
- return(xmlStrndup(buf, 1));
- else if (ctxt->sax != NULL)
- ctxt->sax->characters(ctxt, buf, 0, 1);
+ return(xmlStrndup(buf, 1));
} else {
xmlParserError(ctxt, "xmlParseCharRef: invalid value");
}
@@ -2127,18 +2190,19 @@
/**
* xmlParseEntityRef:
* @ctxt: an XML parser context
- * @inLine: handle it as inline or pass it to SAX as chars ?
*
* parse ENTITY references declarations
*
* [68] EntityRef ::= '&' Name ';'
- * return values: the entity content, or NULL if directly handled (inLine == 0)
+ * return values: the entity ref string or NULL if directly as input stream.
*/
-CHAR *xmlParseEntityRef(xmlParserCtxtPtr ctxt, int inLine) {
+CHAR *xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
CHAR *ret = NULL;
+ const CHAR *q;
CHAR *name;
- xmlEntityPtr entity;
+ xmlParserInputPtr input = NULL;
+ q = CUR_PTR;
if (CUR == '&') {
NEXT;
name = xmlParseName(ctxt);
@@ -2147,40 +2211,18 @@
} else {
if (CUR == ';') {
NEXT;
- entity = xmlGetDocEntity(ctxt->doc, name);
- if (entity == NULL) {
- /* TODO !!! Create a reference ! */
- xmlParserWarning(ctxt,
- "xmlParseEntityRef: &%s; not found\n", name);
- }
/*
- * If we can get the content, push the entity content
- * as the next input stream.
+ * We parsed the entity reference correctly, call SAX
+ * interface for the proper behaviour:
+ * - get a new input stream
+ * - or keep the reference inline
*/
+ if (ctxt->sax)
+ input = ctxt->sax->resolveEntity(ctxt, NULL, name);
+ if (input != NULL)
+ xmlPushInput(ctxt, input);
else {
- switch (entity->type) {
- case XML_INTERNAL_PARAMETER_ENTITY:
- case XML_EXTERNAL_PARAMETER_ENTITY:
- xmlParserError(ctxt,
- "internal: xmlGetDtdEntity returned a general entity\n");
- break;
- case XML_INTERNAL_GENERAL_ENTITY:
- if (inLine)
- ret = entity->content;
- else
- xmlHandleEntity(ctxt, entity);
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- xmlParserWarning(ctxt,
- "xmlParseEntityRef: external entity &%s; not supported\n",
- name);
- break;
- default:
- xmlParserError(ctxt,
- "internal: xmlParseEntityRef: unknown entity type %d\n",
- entity->type);
- }
+ ret = xmlStrndup(q, CUR_PTR - q);
}
} else {
char cst[2] = { '&', 0 };
@@ -2198,18 +2240,18 @@
/**
* xmlParseReference:
* @ctxt: an XML parser context
- * @inLine: handle it as inline or pass it to SAX as chars ?
*
* parse Reference declarations
*
* [67] Reference ::= EntityRef | CharRef
- * return values: the entity content or NULL is handled directly
+ * return values: the entity string or NULL if handled directly by pushing
+ * the entity value as the input.
*/
-CHAR *xmlParseReference(xmlParserCtxtPtr ctxt, int inLine) {
+CHAR *xmlParseReference(xmlParserCtxtPtr ctxt) {
if ((CUR == '&') && (NXT(1) == '#')) {
- return(xmlParseCharRef(ctxt, inLine));
+ return(xmlParseCharRef(ctxt));
} else if (CUR == '&') {
- return(xmlParseEntityRef(ctxt, inLine));
+ return(xmlParseEntityRef(ctxt));
}
return(NULL);
}
@@ -2217,17 +2259,17 @@
/**
* xmlParsePEReference:
* @ctxt: an XML parser context
- * @inLine: handle it as inline or pass it to SAX as chars ?
*
* parse PEReference declarations
*
* [69] PEReference ::= '%' Name ';'
- * return values: the entity content or NULL if handled differently.
+ * return values: the entity content or NULL if handled directly.
*/
-CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt, int inLine) {
+CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt) {
CHAR *ret = NULL;
CHAR *name;
xmlEntityPtr entity;
+ xmlParserInputPtr input;
if (CUR == '%') {
NEXT;
@@ -2241,37 +2283,12 @@
if (entity == NULL) {
xmlParserWarning(ctxt,
"xmlParsePEReference: %%%s; not found\n");
- }
- /*
- * If we can get the content, push the entity content
- * as the next input stream.
- */
- else {
- switch (entity->type) {
- case XML_INTERNAL_PARAMETER_ENTITY:
- if (inLine)
- ret = entity->content;
- else
- xmlNewEntityInputStream(ctxt, entity);
- break;
- case XML_EXTERNAL_PARAMETER_ENTITY:
- xmlParserWarning(ctxt,
- "xmlParsePEReference: external entity %%%s; not supported\n");
- break;
- case XML_INTERNAL_GENERAL_ENTITY:
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- xmlParserError(ctxt,
- "internal: xmlGetDtdEntity returned a general entity\n");
- break;
- default:
- xmlParserError(ctxt,
- "internal: xmlParsePEReference: unknown entity type %d\n",
- entity->type);
- }
+ } else {
+ input = xmlNewEntityInputStream(ctxt, entity);
+ xmlPushInput(ctxt, input);
}
} else {
- char cst[2] = { '&', 0 };
+ char cst[2] = { '%', 0 };
xmlParserError(ctxt, "xmlParsePEReference: expecting ';'\n");
ret = xmlStrndup(cst, 1);
@@ -2339,7 +2356,7 @@
SKIP_BLANKS;
xmlParseMarkupDecl(ctxt);
- xmlParsePEReference(ctxt, 0);
+ xmlParsePEReference(ctxt);
if (CUR_PTR == check) {
xmlParserError(ctxt,
@@ -2387,15 +2404,16 @@
* definition.
*/
-void xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
- CHAR *name, *value = NULL;
+xmlAttrPtr xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
+ CHAR *name;
CHAR *ns;
- xmlNodePtr val = NULL;
+ CHAR *value = NULL;
+ xmlAttrPtr ret;
name = xmlNamespaceParseQName(ctxt, &ns);
if (name == NULL) {
xmlParserError(ctxt, "error parsing attribute name\n");
- return;
+ return(NULL);
}
/*
@@ -2423,31 +2441,30 @@
free(name);
if (value != NULL)
free(value);
- return;
+ return(NULL);
}
if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
(ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
/* a standard namespace definition */
xmlNewNs(node, value, name);
+ free(ns);
if (name != NULL)
free(name);
if (value != NULL)
free(value);
- return;
+ return(NULL);
}
- /*
- * Handle the attribute, this is done by the the SAX back end. The
- * DOM default handling is to build the attribute content tree and
- * link it to the element.
- */
- if (name != NULL) {
- if (ctxt->sax)
- ctxt->sax->attribute(ctxt, name, value);
- free(name);
- }
+ ret = xmlNewProp(ctxt->node, name, NULL);
+ if (ret != NULL)
+ ret->val = xmlStringGetNodeList(ctxt->doc, value);
+
+ if (ns != NULL)
+ free(ns);
if (value != NULL)
- free(value);
+ free(value);
+ free(name);
+ return(ret);
}
/**
@@ -2474,11 +2491,13 @@
CHAR *namespace, *name;
xmlNsPtr ns = NULL;
xmlNodePtr ret = NULL;
+ xmlNodePtr parent = ctxt->node;
if (CUR != '<') return(NULL);
NEXT;
name = xmlNamespaceParseQName(ctxt, &namespace);
+ if (name == NULL) return(NULL);
/*
* Note : the namespace resolution is deferred until the end of the
@@ -2486,6 +2505,17 @@
* an attribute at this level.
*/
ret = xmlNewDocNode(ctxt->doc, ns, name, NULL);
+ if (ret == NULL) {
+ if (namespace != NULL)
+ free(namespace);
+ free(name);
+ return(NULL);
+ }
+
+ /*
+ * We are parsing a new node.
+ */
+ nodePush(ctxt, ret);
/*
* Now parse the attributes, it ends up with the ending
@@ -2513,21 +2543,25 @@
*/
ns = xmlSearchNs(ctxt->doc, ret, namespace);
if (ns == NULL) /* ret still doesn't have a parent yet ! */
- ns = xmlSearchNs(ctxt->doc, ctxt->node, namespace);
+ ns = xmlSearchNs(ctxt->doc, parent, namespace);
xmlSetNs(ret, ns);
if (namespace != NULL)
free(namespace);
/*
- * We are parsing a new node.
- */
- nodePush(ctxt, ret);
-
- /*
* SAX: Start of Element !
*/
if (ctxt->sax != NULL)
ctxt->sax->startElement(ctxt, name);
+ free(name);
+
+ /*
+ * Link the child element
+ */
+ if (ctxt->nodeNr < 2) return(ret);
+ parent = ctxt->nodeTab[ctxt->nodeNr - 2];
+ if (parent != NULL)
+ xmlAddChild(parent, ctxt->node);
return(ret);
}
@@ -2688,10 +2722,27 @@
ret = xmlParseElement(ctxt);
}
/*
- * Fifth case : a reference.
+ * Fifth case : a reference. If if has not been resolved,
+ * parsing returns it's Name, create the node
*/
else if (CUR == '&') {
- xmlParseReference(ctxt, 0);
+ CHAR *val = xmlParseReference(ctxt);
+ if (val != NULL) {
+ if (val[0] != '&') {
+ /*
+ * inline predefined entity.
+ */
+ if (ctxt->sax != NULL)
+ ctxt->sax->characters(ctxt, val, 0, xmlStrlen(val));
+ } else {
+ /*
+ * user defined entity, create a node.
+ */
+ ret = xmlNewReference(ctxt->doc, val);
+ xmlAddChild(ctxt->node, ret);
+ }
+ free(val);
+ }
}
/*
* Last case, text. Note that References are handled directly.
@@ -3266,6 +3317,11 @@
xmlParseDocument(ctxt);
ret = ctxt->doc;
+ free(ctxt->nodeTab);
+ free(ctxt->inputTab);
+ if (input->filename != NULL)
+ free((char *)input->filename);
+ free(input);
free(ctxt);
return(ret);
@@ -3381,6 +3437,11 @@
ret = ctxt->doc;
free(buffer);
+ free(ctxt->nodeTab);
+ free(ctxt->inputTab);
+ if (inputStream->filename != NULL)
+ free((char *)inputStream->filename);
+ free(inputStream);
free(ctxt);
return(ret);
@@ -3415,6 +3476,8 @@
input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
if (input == NULL) {
perror("malloc");
+ free(ctxt->nodeTab);
+ free(ctxt->inputTab);
free(ctxt);
return(NULL);
}
@@ -3434,6 +3497,11 @@
xmlParseDocument(ctxt);
ret = ctxt->doc;
+ free(ctxt->nodeTab);
+ free(ctxt->inputTab);
+ if (input->filename != NULL)
+ free((char *)input->filename);
+ free(input);
free(ctxt);
return(ret);
diff --git a/parser.h b/parser.h
index d0ca958..51ba467 100644
--- a/parser.h
+++ b/parser.h
@@ -128,6 +128,8 @@
extern xmlSAXLocator xmlDefaultSAXLocator;
extern xmlSAXHandler xmlDefaultSAXHandler;
+#include "entities.h"
+
/*
* Interfaces
*/
diff --git a/result/ent1 b/result/ent1
index 14bf428..04e280e 100644
--- a/result/ent1
+++ b/result/ent1
@@ -3,5 +3,4 @@
<!ENTITY xml "Extensible Markup Language">
]>
<EXAMPLE>
- Extensible Markup Language
-</EXAMPLE>
+ &xml;</EXAMPLE>
diff --git a/result/ent2 b/result/ent2
index 754f257..670ce74 100644
--- a/result/ent2
+++ b/result/ent2
@@ -5,6 +5,5 @@
<!ENTITY image SYSTEM "img.gif" NDATA GIF>
]>
<EXAMPLE>
-
- This text is about XML, the Extensible Markup Language and this is an embedded
-</EXAMPLE>
+ &title;
+ This text is about XML, the &xml; and this is an embedded ℑ</EXAMPLE>
diff --git a/result/ent3 b/result/ent3
index b1c0b14..7fb4c7b 100644
--- a/result/ent3
+++ b/result/ent3
@@ -2,6 +2,6 @@
<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
<!ENTITY xml "Extensible Markup Language">
]>
-<EXAMPLE prop1="a&b" prop2="Extensible Markup Language">
+<EXAMPLE prop1="a&b" prop2="&xml;">
Test of entities in attributes.
</EXAMPLE>
diff --git a/result/ent4 b/result/ent4
new file mode 100644
index 0000000..a92194c
--- /dev/null
+++ b/result/ent4
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE>
+ Test of &amp; behaviour a&b .
+</EXAMPLE>
diff --git a/result/p3p b/result/p3p
index 75eec90..5ebda7a 100644
--- a/result/p3p
+++ b/result/p3p
@@ -13,7 +13,7 @@
</STATEMENT>
</USES>
<USES>
- <STATEMENT action="read&write" purp="0" recpnt="0" id="1">
+ <STATEMENT action="read" purp="0" recpnt="0" id="1">
<REF name="User.Shipping."/>
</STATEMENT>
</USES>
diff --git a/test/ent4 b/test/ent4
new file mode 100644
index 0000000..e668b40
--- /dev/null
+++ b/test/ent4
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE >
+ Test of &amp; behaviour a&b .
+</EXAMPLE>
+
diff --git a/tree.c b/tree.c
index 0aeff3c..202f0b8 100644
--- a/tree.c
+++ b/tree.c
@@ -346,6 +346,125 @@
}
/**
+ * xmlStringGetNodeList:
+ * @doc: the document
+ * @value: the value of the attribute
+ *
+ * Parse the value string and build the node list associated. Should
+ * produce a flat tree with only TEXTs and ENTITY_REFs.
+ * return values: a pointer to the first child
+ */
+xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value) {
+ xmlNodePtr ret = NULL, last = NULL;
+ xmlNodePtr node;
+ CHAR *val;
+ const CHAR *cur = value;
+ const CHAR *q;
+
+ if (value == NULL) return(NULL);
+
+ q = cur;
+ while (*cur != 0) {
+ if (*cur == '&') {
+ if (cur != q) {
+ node = xmlNewTextLen(q, cur - q);
+ if (node == NULL) return(ret);
+ if (last == NULL)
+ last = ret = node;
+ else {
+ last->next = node;
+ last = node;
+ }
+ }
+ cur++;
+ q = cur;
+ while ((*cur != 0) && (*cur != ';')) cur++;
+ if (*cur == 0) {
+ fprintf(stderr,
+ "xmlStringGetNodeList: unterminated entity %30s\n", q);
+ return(ret);
+ }
+ if (cur != q) {
+ val = xmlStrndup(q, cur - q);
+ node = xmlNewReference(doc, val);
+ if (node == NULL) return(ret);
+ if (last == NULL)
+ last = ret = node;
+ else {
+ last->next = node;
+ last = node;
+ }
+ free(val);
+ }
+ cur++;
+ q = cur;
+ } else
+ cur++;
+ }
+ if (cur != q) {
+ node = xmlNewTextLen(q, cur - q);
+ if (node == NULL) return(ret);
+ if (last == NULL)
+ last = ret = node;
+ else {
+ last->next = node;
+ last = node;
+ }
+ }
+ return(ret);
+}
+
+/**
+ * xmlNodeListGetString:
+ * @doc: the document
+ * @list: a Node list
+ * @inLine: should we replace entity contents or show their external form
+ *
+ * Returns the string equivalent to the text contained in the Node list
+ * made of TEXTs and ENTITY_REFs
+ * return values: a pointer to the string copy, the calller must free it.
+ */
+CHAR *xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
+ xmlNodePtr node = list;
+ CHAR *ret = NULL;
+ xmlEntityPtr ent;
+
+ if (list == NULL) return(NULL);
+
+ while (node != NULL) {
+ if (node->type == XML_TEXT_NODE) {
+ if (inLine)
+ ret = xmlStrcat(ret, node->content);
+ else
+ ret = xmlStrcat(ret, xmlEncodeEntities(doc, node->content));
+ } else if (node->type == XML_ENTITY_REF_NODE) {
+ if (inLine) {
+ ent = xmlGetDocEntity(doc, node->name);
+ if (ent != NULL)
+ ret = xmlStrcat(ret, ent->content);
+ else
+ ret = xmlStrcat(ret, node->content);
+ } else {
+ CHAR buf[2];
+ buf[0] = '&'; buf[1] = 0;
+ ret = xmlStrncat(ret, buf, 1);
+ ret = xmlStrcat(ret, node->name);
+ buf[0] = ';'; buf[1] = 0;
+ ret = xmlStrncat(ret, buf, 1);
+ }
+ }
+#if 0
+ else {
+ fprintf(stderr, "xmlGetNodeListString : invalide node type %d\n",
+ node->type);
+ }
+#endif
+ node = node->next;
+ }
+ return(ret);
+}
+
+/**
* xmlNewProp:
* @node: the holding node
* @name: the name of the attribute
@@ -375,9 +494,9 @@
cur->node = node;
cur->name = xmlStrdup(name);
if (value != NULL)
- cur->value = xmlStrdup(value);
+ cur->val = xmlStringGetNodeList(node->doc, value);
else
- cur->value = NULL;
+ cur->val = NULL;
#ifndef WITHOUT_CORBA
cur->_private = NULL;
cur->vepv = NULL;
@@ -401,6 +520,48 @@
}
/**
+ * xmlNewDocProp:
+ * @doc: the document
+ * @name: the name of the attribute
+ * @value: the value of the attribute
+ *
+ * Create a new property carried by a document.
+ * return values: a pointer to the attribute
+ */
+xmlAttrPtr xmlNewDocProp(xmlDocPtr doc, const CHAR *name, const CHAR *value) {
+ xmlAttrPtr cur;
+
+ if (name == NULL) {
+ fprintf(stderr, "xmlNewProp : name == NULL\n");
+ return(NULL);
+ }
+
+ /*
+ * Allocate a new property and fill the fields.
+ */
+ cur = (xmlAttrPtr) malloc(sizeof(xmlAttr));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewProp : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->type = XML_ATTRIBUTE_NODE;
+ cur->node = NULL;
+ cur->name = xmlStrdup(name);
+ if (value != NULL)
+ cur->val = xmlStringGetNodeList(doc, value);
+ else
+ cur->val = NULL;
+#ifndef WITHOUT_CORBA
+ cur->_private = NULL;
+ cur->vepv = NULL;
+#endif
+
+ cur->next = NULL;
+ return(cur);
+}
+
+/**
* xmlFreePropList:
* @cur: the first property in the list
*
@@ -431,7 +592,7 @@
return;
}
if (cur->name != NULL) free((char *) cur->name);
- if (cur->value != NULL) free((char *) cur->value);
+ if (cur->val != NULL) xmlFreeNodeList(cur->val);
memset(cur, -1, sizeof(xmlAttr));
free(cur);
}
@@ -443,9 +604,11 @@
* @content: the text content if any
*
* Creation of a new node element. @ns and @content are optionnal (NULL).
+ * If content is non NULL, a child list containing the TEXTs and
+ * ENTITY_REFs node will be created.
* return values: a pointer to the new node object.
*/
-xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content) {
+xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name) {
xmlNodePtr cur;
if (name == NULL) {
@@ -473,14 +636,11 @@
cur->name = xmlStrdup(name);
cur->ns = ns;
cur->nsDef = NULL;
+ cur->content = NULL;
#ifndef WITHOUT_CORBA
cur->_private = NULL;
cur->vepv = NULL;
#endif
- if (content != NULL)
- cur->content = xmlStrdup(content);
- else
- cur->content = NULL;
return(cur);
}
@@ -499,8 +659,12 @@
const CHAR *name, CHAR *content) {
xmlNodePtr cur;
- cur = xmlNewNode(ns, name, content);
- if (cur != NULL) cur->doc = doc;
+ cur = xmlNewNode(ns, name);
+ if (cur != NULL) {
+ cur->doc = doc;
+ if (content != NULL)
+ cur->childs = xmlStringGetNodeList(doc, content);
+ }
return(cur);
}
@@ -543,6 +707,55 @@
}
/**
+ * xmlNewReference:
+ * @doc: the document
+ * @name: the reference name, or the reference string with & and ;
+ *
+ * Creation of a new reference node.
+ * return values: a pointer to the new node object.
+ */
+xmlNodePtr xmlNewReference(xmlDocPtr doc, const CHAR *name) {
+ xmlNodePtr cur;
+ xmlEntityPtr ent;
+
+ /*
+ * Allocate a new node and fill the fields.
+ */
+ cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+ if (cur == NULL) {
+ fprintf(stderr, "xmlNewText : malloc failed\n");
+ return(NULL);
+ }
+
+ cur->type = XML_ENTITY_REF_NODE;
+ cur->doc = NULL;
+ cur->parent = NULL;
+ cur->next = NULL;
+ cur->prev = NULL;
+ cur->childs = NULL;
+ cur->properties = NULL;
+ if (name[0] == '&') {
+ int len;
+ name++;
+ len = xmlStrlen(name);
+ if (name[len - 1] == ';')
+ cur->name = xmlStrndup(name, len - 1);
+ else
+ cur->name = xmlStrndup(name, len);
+ } else
+ cur->name = xmlStrdup(name);
+ cur->ns = NULL;
+ cur->nsDef = NULL;
+
+ ent = xmlGetDocEntity(doc, cur->name);
+ if (ent != NULL)
+ cur->content = ent->content;
+ else
+ cur->content = NULL;
+ return(cur);
+}
+
+/**
* xmlNewDocText:
* @doc: the document
* @content: the text content
@@ -559,7 +772,7 @@
}
/**
- * xmlNewText:
+ * xmlNewTextLen:
* @content: the text content
* @len: the text len.
*
@@ -676,7 +889,8 @@
*
*
* Creation of a new child element, added at the end of @parent childs list.
- * @ns and @content parameters are optionnal (NULL).
+ * @ns and @content parameters are optionnal (NULL). If content is non NULL,
+ * a child list containing the TEXTs and ENTITY_REFs node will be created.
* return values: a pointer to the new node object.
*/
xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
@@ -697,18 +911,15 @@
* Allocate a new node
*/
if (ns == NULL)
- cur = xmlNewNode(parent->ns, name, content);
+ cur = xmlNewDocNode(parent->doc, parent->ns, name, content);
else
- cur = xmlNewNode(ns, name, content);
+ cur = xmlNewDocNode(parent->doc, ns, name, content);
if (cur == NULL) return(NULL);
/*
* add the new element at the end of the childs list.
*/
- if (content == NULL)
- cur->type = XML_ELEMENT_NODE;
- else
- cur->type = XML_TEXT_NODE;
+ cur->type = XML_ELEMENT_NODE;
cur->parent = parent;
cur->doc = parent->doc;
if (parent->childs == NULL) {
@@ -754,6 +965,23 @@
*/
cur->parent = parent;
cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
+ /*
+ * Handle the case where parent->content != NULL, in that case it will
+ * create a intermediate TEXT node.
+ */
+ if (parent->content != NULL) {
+ xmlNodePtr text;
+
+ text = xmlNewDocText(parent->doc, parent->content);
+ if (text != NULL) {
+ text->next = parent->childs;
+ if (text->next != NULL)
+ text->next->prev = text;
+ parent->childs = text;
+ free(parent->content);
+ parent->content = NULL;
+ }
+ }
if (parent->childs == NULL) {
parent->childs = cur;
} else {
@@ -824,9 +1052,14 @@
fprintf(stderr, "xmlFreeNode : node == NULL\n");
return;
}
- if (cur->properties != NULL) xmlFreePropList(cur->properties);
+ cur->doc = NULL;
+ cur->parent = NULL;
+ cur->next = NULL;
+ cur->prev = NULL;
if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
- if (cur->content != NULL) free(cur->content);
+ if (cur->properties != NULL) xmlFreePropList(cur->properties);
+ if (cur->type != XML_ENTITY_REF_NODE)
+ if (cur->content != NULL) free(cur->content);
if (cur->name != NULL) free((char *) cur->name);
if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef);
memset(cur, -1, sizeof(xmlNode));
@@ -989,20 +1222,22 @@
* @name: the attribute name
*
* Search and get the value of an attribute associated to a node
+ * This does the entity substitution.
* return values: the attribute value or NULL if not found.
*/
const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) {
xmlAttrPtr prop = node->properties;
while (prop != NULL) {
- if (!xmlStrcmp(prop->name, name)) return(prop->value);
+ if (!xmlStrcmp(prop->name, name))
+ return(xmlNodeListGetString(node->doc, prop->val, 1));
prop = prop->next;
}
return(NULL);
}
/**
- * xmlGetProp:
+ * xmlSetProp:
* @node: the node
* @name: the attribute name
* @value: the attribute value
@@ -1015,11 +1250,11 @@
while (prop != NULL) {
if (!xmlStrcmp(prop->name, name)) {
- if (prop->value != NULL)
- free((char *) prop->value);
- prop->value = NULL;
+ if (prop->val != NULL)
+ xmlFreeNode(prop->val);
+ prop->val = NULL;
if (value != NULL)
- prop->value = xmlStrdup(value);
+ prop->val = xmlStringGetNodeList(node->doc, value);
return(prop);
}
prop = prop->next;
@@ -1267,16 +1502,20 @@
* Dump an XML attribute
*/
static void xmlAttrDump(xmlDocPtr doc, xmlAttrPtr cur) {
+ CHAR *value;
+
if (cur == NULL) {
fprintf(stderr, "xmlAttrDump : property == NULL\n");
return;
}
xmlBufferWriteChar(" ");
xmlBufferWriteCHAR(cur->name);
- if (cur->value) {
+ value = xmlNodeListGetString(doc, cur->val, 0);
+ if (value) {
xmlBufferWriteChar("=\"");
- xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->value));
+ xmlBufferWriteCHAR(value);
xmlBufferWriteChar("\"");
+ free(value);
}
}
@@ -1309,18 +1548,30 @@
* Dump an XML node list, recursive behaviour,children are printed too.
*/
static void xmlNodeListDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
+ int needIndent = 0, i;
+
if (cur == NULL) {
fprintf(stderr, "xmlNodeListDump : node == NULL\n");
return;
}
while (cur != NULL) {
+ if ((cur->type != XML_TEXT_NODE) &&
+ (cur->type != XML_ENTITY_REF_NODE)) {
+ if (!needIndent) {
+ needIndent = 1;
+ xmlBufferWriteChar("\n");
+ }
+ }
xmlNodeDump(doc, cur, level);
cur = cur->next;
}
+ if ((xmlIndentTreeOutput) && (needIndent))
+ for (i = 1;i < level;i++)
+ xmlBufferWriteChar(" ");
}
/**
- * xmlNodeListDump:
+ * xmlNodeDump:
* @doc: the document
* @cur: the current node
* @level: the imbrication level for indenting
@@ -1347,6 +1598,12 @@
}
return;
}
+ if (cur->type == XML_ENTITY_REF_NODE) {
+ xmlBufferWriteChar("&");
+ xmlBufferWriteCHAR(cur->name);
+ xmlBufferWriteChar(";");
+ return;
+ }
if (xmlIndentTreeOutput)
for (i = 0;i < level;i++)
xmlBufferWriteChar(" ");
@@ -1371,11 +1628,7 @@
if (cur->content != NULL)
xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
if (cur->childs != NULL) {
- xmlBufferWriteChar("\n");
xmlNodeListDump(doc, cur->childs, level + 1);
- if (xmlIndentTreeOutput)
- for (i = 0;i < level;i++)
- xmlBufferWriteChar(" ");
}
xmlBufferWriteChar("</");
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
@@ -1531,7 +1784,7 @@
gzFile zoutput = NULL;
char mode[15];
#endif
- FILE *output;
+ FILE *output = NULL;
int ret;
#ifdef HAVE_ZLIB_H
@@ -1584,7 +1837,7 @@
doc = xmlNewDoc("1.0");
ns1 = xmlNewNs(doc, "http://www.ietf.org/standards/dav/", "D");
ns2 = xmlNewNs(doc, "http://www.w3.com/standards/z39.50/", "Z");
- doc->root = xmlNewNode(ns1, "multistatus", NULL);
+ doc->root = xmlNewDocNode(doc, ns1, "multistatus", NULL);
tree = xmlNewChild(doc->root, NULL, "response", NULL);
subtree = xmlNewChild(tree, NULL, "prop", NULL);
xmlNewChild(subtree, ns2, "Authors", NULL);
diff --git a/tree.h b/tree.h
index 91677a6..2ebe2cd 100644
--- a/tree.h
+++ b/tree.h
@@ -16,7 +16,30 @@
#endif
/*
- * Type definitions
+ * The different element types carried by an XML tree
+ *
+ * NOTE: This is synchronized with DOM Level1 values
+ * See http://www.w3.org/TR/REC-DOM-Level-1/
+ */
+typedef enum {
+ XML_ELEMENT_NODE= 1,
+ XML_ATTRIBUTE_NODE= 2,
+ XML_TEXT_NODE= 3,
+ XML_CDATA_SECTION_NODE= 4,
+ XML_ENTITY_REF_NODE= 5,
+ XML_ENTITY_NODE= 6,
+ XML_PI_NODE= 7,
+ XML_COMMENT_NODE= 8,
+ XML_DOCUMENT_NODE= 9,
+ XML_DOCUMENT_TYPE_NODE= 10,
+ XML_DOCUMENT_FRAG_NODE= 11,
+ XML_NOTATION_NODE= 12
+} xmlElementType;
+
+/*
+ * Currently we use only 8bit chars internal representation, but
+ * the parser is not tied to that, just define UNICODE to switch to
+ * a 16 bits representation.
*/
#ifdef UNICODE
typedef unsigned short CHAR;
@@ -84,37 +107,22 @@
void *_private; /* for Corba, must be first ! */
void *vepv; /* for Corba, must be next ! */
#endif
- int type; /* XML_ATTRIBUTE_NODE, must be third ! */
+ xmlElementType type; /* XML_ATTRIBUTE_NODE, must be third ! */
struct xmlNode *node; /* attr->node link */
struct xmlAttr *next; /* parent->childs link */
const CHAR *name; /* the name of the property */
- const CHAR *value; /* the value of the property */
+ struct xmlNode *val; /* the value of the property */
} xmlAttr, *xmlAttrPtr;
/*
* A node in an XML tree.
- * NOTE: This is synchronized with DOM Level1 values
- * See http://www.w3.org/TR/REC-DOM-Level-1/
*/
-#define XML_ELEMENT_NODE 1
-#define XML_ATTRIBUTE_NODE 2
-#define XML_TEXT_NODE 3
-#define XML_CDATA_SECTION_NODE 4
-#define XML_ENTITY_REF_NODE 5
-#define XML_ENTITY_NODE 6
-#define XML_PI_NODE 7
-#define XML_COMMENT_NODE 8
-#define XML_DOCUMENT_NODE 9
-#define XML_DOCUMENT_TYPE_NODE 10
-#define XML_DOCUMENT_FRAG_NODE 11
-#define XML_NOTATION_NODE 12
-
typedef struct xmlNode {
#ifndef XML_WITHOUT_CORBA
void *_private; /* for Corba, must be first ! */
void *vepv; /* for Corba, must be next ! */
#endif
- int type; /* type number in the DTD, must be third ! */
+ xmlElementType type; /* type number in the DTD, must be third ! */
struct xmlDoc *doc; /* the containing document */
struct xmlNode *parent; /* child->parent link */
struct xmlNode *next; /* next sibling link */
@@ -135,7 +143,7 @@
void *_private; /* for Corba, must be first ! */
void *vepv; /* for Corba, must be next ! */
#endif
- int type; /* XML_DOCUMENT_NODE, must be second ! */
+ xmlElementType type; /* XML_DOCUMENT_NODE, must be second ! */
char *name; /* name/filename/URI of the document */
const CHAR *version; /* the XML version string */
const CHAR *encoding; /* encoding, if any */
@@ -165,22 +173,27 @@
extern void xmlFreeNs(xmlNsPtr cur);
extern xmlDocPtr xmlNewDoc(const CHAR *version);
extern void xmlFreeDoc(xmlDocPtr cur);
+extern xmlAttrPtr xmlNewDocProp(xmlDocPtr doc, const CHAR *name,
+ const CHAR *value);
extern xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
const CHAR *value);
extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
const CHAR *value);
extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
+extern xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value);
+extern CHAR *xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine);
extern void xmlFreePropList(xmlAttrPtr cur);
extern void xmlFreeProp(xmlAttrPtr cur);
extern xmlNodePtr xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
const CHAR *name, CHAR *content);
-extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content);
+extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name);
extern xmlNodePtr xmlNewDocText(xmlDocPtr doc, const CHAR *content);
extern xmlNodePtr xmlNewText(const CHAR *content);
extern xmlNodePtr xmlNewDocTextLen(xmlDocPtr doc, const CHAR *content, int len);
extern xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
extern xmlNodePtr xmlNewDocComment(xmlDocPtr doc, CHAR *content);
extern xmlNodePtr xmlNewComment(CHAR *content);
+extern xmlNodePtr xmlNewReference(xmlDocPtr doc, const CHAR *name);
extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
extern xmlNodePtr xmlGetLastChild(xmlNodePtr node);
extern int xmlNodeIsText(xmlNodePtr node);