@@ -103,7 +103,7 @@ parsedParsleyPtr parsley_parse_string(parsleyPtr parsley, char* string, size_t s
103103
104104static char *
105105xpath_of (xmlNodePtr node ) {
106- if (node == NULL || node -> name == NULL && node -> parent == NULL ) return strdup ("/" );
106+ if (node == NULL || node -> name == NULL || node -> parent == NULL ) return strdup ("/" );
107107
108108 struct ll * ptr = (struct ll * ) calloc (sizeof (struct ll * ), 1 );
109109
@@ -118,6 +118,7 @@ xpath_of(xmlNodePtr node) {
118118 }
119119
120120 struct printbuf * buf = printbuf_new ();
121+ sprintbuf (buf , "" );
121122 while (ptr -> name != NULL ) {
122123 sprintbuf (buf , "/%s" , ptr -> name );
123124 struct ll * last = ptr ;
@@ -126,7 +127,7 @@ xpath_of(xmlNodePtr node) {
126127 }
127128 free (ptr );
128129
129- char * str = strdup (buf -> buf );
130+ char * str = strdup (strlen ( buf -> buf ) ? buf -> buf : "/" );
130131 printbuf_free (buf );
131132 return str ;
132133}
@@ -148,17 +149,15 @@ unlink(xmlNodePtr xml) {
148149 }
149150}
150151
151- static bool
152- is_root (xmlElementPtr xml ) {
153- return xml != NULL && xml -> name != NULL && xml -> prefix != NULL && !strcmp (xml -> name , "root" ) && !strcmp (xml -> prefix , "parsley" );
154- }
155-
156- // static bool
157- // is_root(xmlNodePtr node) {
158- // return !strcmp(node->ns->prefix, "parsley") && !strcmp(node->name, "root");
152+ // static bool
153+ // is_root(xmlElementPtr xml) {
154+ // return xml != NULL && xml->name != NULL && xml->prefix != NULL && !strcmp(xml->name, "root") && !strcmp(xml->prefix, "parsley");
159155// }
160- //
161156
157+ static bool
158+ is_root (xmlNodePtr node ) {
159+ return node != NULL && node -> ns != NULL && !strcmp (node -> ns -> prefix , "parsley" ) && !strcmp (node -> name , "root" );
160+ }
162161
163162int compare_pos (const void * a , const void * b )
164163{
@@ -281,24 +280,28 @@ collate(xmlNodePtr xml) {
281280
282281static void
283282prune (parsedParsleyPtr ptr , xmlNodePtr xml , char * err ) {
284- if (xml == NULL ) return ;
283+ if (xml == NULL || is_root ( xml ) ) return ;
285284 bool optional = xmlGetProp (xml , "optional" ) != NULL ;
286285 if (optional ) {
287286 unlink (xml );
288287 visit (ptr , xml -> parent , err );
288+ // fprintf(stderr, "optional ok\n");
289289 return ;
290290 } else {
291291 if (err == NULL ) asprintf (& err , "%s was empty" , xpath_of (xml ));
292292 if (!is_root (xml -> parent )) {
293+ // fprintf(stderr, "prune up: %s\n", xml->parent->name);
293294 prune (ptr , xml -> parent , err );
294295 } else {
296+ // fprintf(stderr, "error out\n");
295297 ptr -> error = err ;
296298 }
297299 }
298300}
299301
300302static void
301303visit (parsedParsleyPtr ptr , xmlNodePtr xml , char * err ) {
304+ if (xml == NULL ) return ;
302305 if (xml -> type != XML_ELEMENT_NODE ) return ;
303306 xmlNodePtr child = xml -> children ;
304307 xmlNodePtr parent = xml -> parent ;
@@ -318,13 +321,14 @@ visit(parsedParsleyPtr ptr, xmlNodePtr xml, char* err) {
318321
319322static bool
320323xml_empty (xmlNodePtr xml ) {
324+ // fprintf(stderr, "%s\n", xml->name);
321325 xmlNodePtr child = xml -> children ;
322326 while (child != NULL ) {
323327 if (child -> type != XML_TEXT_NODE ) return false;
324328 if (strlen (child -> content )) return false;
325329 child = child -> next ;
326330 }
327- // printf("hello!\n");
331+ // printf("hello!\n");
328332 return true;
329333}
330334
@@ -529,6 +533,7 @@ render(contextPtr c) {
529533 char * filter = resolve_filter (c );
530534 char * expr = resolve_expr (c );
531535 char * scope = filter == NULL ? expr : filter ;
536+ char * group_optional = (c -> flags & PARSLEY_BANG ) ? "" : " optional=\"true\"" ;
532537 bool magic_children = c -> array && filter == NULL ;
533538 bool simple_array = c -> array && filter != NULL ;
534539 bool filtered = filter != NULL ;
@@ -537,7 +542,7 @@ render(contextPtr c) {
537542 if (c -> array ) sprintbuf (c -> buf , "<parsley:groups>\n" );
538543 if (filtered ) sprintbuf (c -> buf , "<xsl:for-each select=\"%s\">\n" , filter );
539544 if (filtered && !multiple ) sprintbuf (c -> buf , "<xsl:if test=\"position()=1\">\n" );
540- if (multiple ) sprintbuf (c -> buf , "<parsley:group optional=\"true\" >\n" );
545+ if (multiple ) sprintbuf (c -> buf , "<parsley:group%s >\n" , group_optional );
541546
542547 sprintbuf (c -> buf , "<xsl:attribute name=\"position\"><xsl:value-of select=\"count(preceding::*) + count(ancestor::*)\"/></xsl:attribute>\n" );
543548
0 commit comments