emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problems with xml-parse-string


From: Wojciech Meyer
Subject: Re: Problems with xml-parse-string
Date: Thu, 23 Sep 2010 22:58:14 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50

Chong Yidong <address@hidden> writes:

> Leo <address@hidden> writes:
>
>> On 2010-09-23 00:59 +0100, Stefan Monnier wrote:
>>> FWIW, while I haven't use sml.el much, the little bit I've used it was
>>> not particularly pleasant, partly because of the odd format. I don't
>>> know how/why the xml.el was chosen and how much thought was put into
>>> it, but my experience with it is not 100% positive.
>>
>> That looks like my experience too.
>
> The main differences in the "new" format are (i) listing attributes as
> (:foo bar) inside the element list, rather than in an alist after the
> element name, (ii) listing text as (text "foo") rather than "foo", and
> (iii) the as-yet-unresolved issue with XML namespaces, which probably
> needs to be fixed in xml.c.
>
> Point (i) is a broken design choice, as I already pointed out.  As for
> (ii), it is a little nicer to take the cdr of each list member without
> checking for stringp.  If others thing this is a really good change, I
> won't object, though it seems pretty trivial to me.  We can add an
> optional flag to the xml-* functions to toggle between the two
> representations.

This patch fixes all the problems above and gives SXML conforming
representation of the elements tree.

Obviously we would need to patch `xml.el', and provide an interface for
accessing tree elements.

Thanks,
Wojciech

>From 7db230f57fe9b7904d4d55e1fbe90a7522bd38a5 Mon Sep 17 00:00:00 2001
From: Wojciech Meyer <address@hidden>
Date: Thu, 23 Sep 2010 22:45:32 +0100
Subject: [PATCH] Support for SXML AST.

        * xml.c (make_dom): Make output to conform with
          SXML spec.
        * ChangeLog: Add entry.

Signed-off-by: Wojciech Meyer <address@hidden>
---
 src/ChangeLog |    5 ++++
 src/xml.c     |   60 ++++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 2dd892f..b11d291 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2010-09-23  Wojciech Meyer  <address@hidden>
+
+       * xml.c (make_dom): Make output to conform with
+         SXML spec.
+
 2010-09-22  Eli Zaretskii  <address@hidden>
 
        * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal)
diff --git a/src/xml.c b/src/xml.c
index 5829f1d..9dc0931 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -28,7 +28,8 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include "lisp.h"
 #include "buffer.h"
 
-Lisp_Object make_dom (xmlNode *node)
+static Lisp_Object 
+make_dom (xmlNode *node)
 {
   if (node->type == XML_ELEMENT_NODE)
     {
@@ -36,27 +37,60 @@ Lisp_Object make_dom (xmlNode *node)
       xmlNode *child;
       xmlAttr *property;
       Lisp_Object plist = Qnil;
+      int was_element_node = 0;
+      
+      /* First add the attributes.  */
 
-      /* First add the attributes. */
       property = node->properties;
-      while (property != NULL)
+
+      /* Don't add nil if no properties */
+      if (property != NULL)
        {
-         if (property->children &&
-             property->children->content)
+         /* Add special `@' node containing properties */
+         plist = Fcons(intern("@"),Qnil);
+
+         while (property != NULL)
            {
-             plist = Fcons (Fcons (intern (property->name),
-                                   build_string (property->children->content)),
-                            plist);
+             if (property->children &&
+                 property->children->content)
+               {
+                 plist = 
+                   Fcons 
+                   (Fcons (intern (property->name),
+                           Fcons (build_string (property->children->content), 
+                                  Qnil)),
+                    plist);
+               }
+             property = property->next;
            }
-         property = property->next;
+         result = Fcons (Fnreverse (plist), result);
        }
-      result = Fcons (Fnreverse (plist), result);
-
       /* Then add the children of the node. */
+
       child = node->children;
+
+      /* First try to lookup for elements 
+        if any found, prohibit adding any text elements */
+
       while (child != NULL)
        {
-         result = Fcons (make_dom (child), result);
+         if (child->type == XML_ELEMENT_NODE)
+           {
+             was_element_node = 1;
+             result = Fcons (make_dom (child), result);
+           }
+
+         child = child->next;
+       }
+      
+      child = node->children;
+      
+      while (!was_element_node && child != NULL)
+       {
+
+         if ( child->type == XML_TEXT_NODE )
+           result = Fcons (make_dom (child), result);
+
          child = child->next;
        }
 
@@ -73,7 +107,7 @@ Lisp_Object make_dom (xmlNode *node)
     return Qnil;
 }
 
-static Lisp_Object
+INLINE static Lisp_Object
 parse_string (Lisp_Object string, Lisp_Object base_url, int htmlp)
 {
   xmlDoc *doc;
-- 
1.7.0.4


reply via email to

[Prev in Thread] Current Thread [Next in Thread]