Subject: bug#11916: 24.1.50; Making url-dav work

From: Stefan Monnier <[email-masked]>
Date: Wed, 18 Jul 2012 08:25:27 -0400

> I started rewriting url-dav to work with the cons's returned by xml.el,
> but it's tedious work and, more importantly, makes the code really
> ugly.

Could you show us some example of the ugliness to get a feeling for the
tradeoffs?  I see you'd need to change url-dav-find-parser, but that
doesn't sound so terrible, so the ugliness seems to come from parts that
aren't as immediately apparent.

> Instead, I now just use a small function to replace the cons's in
> xml.el's output with the plain symbols the package expects. Please find
> the patch attached.

Rather than provide a "changexml" function which traverses the XML tree
and changes the cons to symbols, how 'bout changing xml-parse-region?

I have the vague impression that the representation was changed from
symbols to cons cells on the premise that it was more Lispy (would
avoid (re)parsing the symbol names), but if it turns out to be a pain
to use, maybe that was a bad call (basically, you're saying that you
never need/want to parse those QNAMES).

Another issue is: what does libxml-parse-xml-region do (it would be better
to try and reduce the difference between the two)?

        Stefan

> --- url-dav.el	2012-07-11 22:34:49.401721367 +0200
> +++ url-dav.el_patched	2012-07-11 22:33:34.504867729 +0200
> @@ -395,10 +395,15 @@
>  		 url-http-content-type
>  		 (string-match "\\`\\(text\\|application\\)/xml"
>  			       url-http-content-type))
> -		(setq tree (xml-parse-region (point) (point-max)))))
> +		(setq tree (xml-parse-region (point) (point-max) nil nil t))))
>  	;; Clean up after ourselves.
>  	(kill-buffer buffer)))
 
> +    ;; This package was initially written for a different kind of
> +    ;; QNAMES expansion, hence we have now to rewrite those so that
> +    ;; for example ("DAV:" . "foo") becomes the symbol 'DAV:foo.
> +    (url-dav-changexml (car tree))
> +
>      ;; We should now be
>      (if (eq (xml-node-name (car tree)) 'DAV:multistatus)
>  	(url-dav-dispatch-node (car tree))
> @@ -411,6 +416,21 @@
>  	;; nobody but us needs to know the difference.
>  	(list (cons url properties))))))
 
> +(defun url-dav-changexml (node)
> +  "Rewrite all expanded names in NODE to plain symbols.
> +That means, all cons produced from `xml-parse-region'
> +like (\"DAV:\" .  \"foo\") become plain symbols DAV:foo.
> +This replacement happens in-place."
> +  (when (consp node)
> +    (let ((name (xml-node-name node))
> +	  (children (xml-node-children node)))
> +      (when (and (consp name)
> +		 (equal (car name) "DAV:"))
> +	(setcar node (intern (concat "DAV:" (cdr name)))))
> +      (when children
> +	(dolist (cur children)
> +	  (url-dav-changexml cur))))))
> +
>  (defun url-dav-request (url method tag body
>  				 &optional depth headers namespaces)
>    "Perform WebDAV operation METHOD on URL.  Return the parsed responses.