Archive for the ‘Generative XML’ Category

libxml2 tree: NULL vs empty string

Friday, March 11th, 2005

In libxml2, C calls

xmlNewPI("name", NULL);
xmlNewPI("name", "");

produce the following processing instructions

<?name?>
<?name ?>

(notice the space in the second case). At the first moment I though that I shouldn’t allow the first variant. But then reminded that in XML absence of node and empty node are sometimes very different things. So let both variants be.

Then I tested two variants for another node type:

xmlNewComment(NULL);
xmlNewComment("");

The second case produced the expected result

<---->

but the first variant seems broken. In serialized XML, I have no comments at all!

Anyway, I decided to have difference between nothing and empty string. I feel it can be used somehow,

following bad practises

Friday, March 11th, 2005

Some days ago I used “goto”s in my C code. Now that C function have got a new bad feature: a set of local variables named “scm”, “scm2″, “scm3″, “scm4″. Anyway, I still think that the code is good.

Skeleton is forming

Thursday, March 10th, 2005

Unexpectedly, I’ve got too little time for programming this evening. Anyway, the new code now can convert elements and attributes.

XSLT:

<x:stylesheet
  xmlns:x = "http://www.w3.org/1999/XSL/Transform"
  xmlns:s = "http://uucode.com/xslt/scheme"
  x:extension-element-prefixes="s"
  version = "1.0">

<x:output indent="yes"/>

<x:template match="/">
  <s:scheme>
    '(article  (@ (id "hw"))
      (title "Hello")
      (para
        "Hello, "
        (object "World")
        "!"))
  </s:scheme>
</x:template>

</x:stylesheet>

Result:

<article id="hw">
  <title>Hello</title>
  <para>Hello, <object>World</object>!</para>
</article>

It was hard to implement conversion of attributes. I’ve used a small trick which is not guaranteed to work because I’ve misused the API a bit. I hope to write about it soon.

the road to hell is paved with good intentions

Wednesday, March 9th, 2005

I’ve spent the evening investigating why I was getting a core dump. It was not an easy task because the code was in a plugin (so it was hard to set a breakpoint) and the data structures were full of links (libxml) or the mess (Guile).

Well, suppose you have the empty element node par and two text nodes node1 and node2 with the content text1 and text1. You adds nodes node1 and node2 as children to the node par. What the structure do you get? A node with two text children? No, it’s too boring. Excerpt from the xmlAddChild description:

Add a new node to @parent, at the end of the child (or property) list merging adjacent TEXT nodes (in which case @cur is freed)

It was my problem. I was reusing a freed node. It was a big problem because I had to reuse it, and the automatical merging broke the mapping between SCM values and xml nodes. Well, the solution is trivial: I don’t map text nodes anymore, and now I see that it is the right way.

Conclusion: sometimes even the road to hell is useful.

By the way, I’ve implemented conversion of Scheme lists to XML nodesets. The problem above arose while working on the conversion.

links, trees, forest, infinity

Tuesday, March 8th, 2005

On mapping from Scheme values to libxml nodes. It is reasonable to map the same physical values to the same physical nodes. But it causes unexpected results. Consider the stylesheet:

<x:stylesheet
  xmlns:x = "http://www.w3.org/1999/XSL/Transform"
  xmlns:s = "http://uucode.com/xslt/scheme"
  x:extension-element-prefixes="s"
  version     = "1.0">

<s:init>
  (define foo 777)
</s:init>

<x:template match="/">
  <x>
    <s:scheme>foo</s:scheme>
    <s:scheme>foo</s:scheme>
    <!-- <y><s:scheme>foo</s:scheme></y> -->
  </x>
</x:template>

</x:stylesheet>

One can expect to get the following result:

<x>777777</x>

But the right answer is:

<x>777</x>

As I found, libxml performs a set of checks while adding a child. One of the checks is that the same node isn’t inserted twice.

And what happens when the part of stylesheet is uncommented? It produces such a tree structure which isn’t expected by libxml. As result, serializer enters infinitive loop till core dump.

from Scheme values to XML nodes

Tuesday, March 8th, 2005

Conversion of some basic Scheme types (string, boolean, char, number) to XML nodes now works. The stylesheet

<x:stylesheet
  xmlns:x = "http://www.w3.org/1999/XSL/Transform"
  xmlns:s = "http://uucode.com/xslt/scheme"
  x:extension-element-prefixes="s"
  version     = "1.0">

<x:template match="/">
  <x>
    <x1><s:scheme>"string value"</s:scheme></x1>
    <x2><s:scheme>(> 2 3)</s:scheme></x2>
    <x3><s:scheme>(/ 777 2)</s:scheme></x3>
    <x4><s:scheme>#A</s:scheme></x4>
  </x>
</x:template>

</x:stylesheet>

produces, as expected

<x>
  <x1>string value</x1>
  <x2>false</x2>
  <x3>388.5</x3>
  <x4>A</x4>
</x>

goto considered

Tuesday, March 8th, 2005

It’s well-known that goto is considered harmful. But… I’ve just written a small C function of approximately 70 lines with 5 gotos and two goto targets. And I like the code.

xfind is not the standard find

Monday, March 7th, 2005

The title “Find with XPath over file system” is a bit misleading. It is not the first time when I’ve got a question like:

When you say “The standard UNIX utility find now supports XPath”, does that mean that this will be included in the standard find?

Now I’ve been asked at Lambda the Ultimate (and I like being noticed there).

The answer is:

No, it will never be included in the standard find: http://lists.gnu.org/archive/html/bug-findutils/2005-01/msg00107.html, and I completely agree.

It looks like the title is a bit misleading. I wanted to emphasize that I hadn’t written a program from scratch, but added the XPath facility to a legacy code, and the legacy code is the standard find.

XSLT element “scheme:init” works

Monday, March 7th, 2005

I’m working on embedding Guile (Scheme interpreter) to xsltproc. I’ve introduced the element “init” to contain Scheme initialization code and added (I suppose, sometimes redundant) error checks. Well, it works now:

<x:stylesheet
  xmlns:x = "http://www.w3.org/1999/XSL/Transform"
  xmlns:s = "http://uucode.com/xslt/scheme"
  x:extension-element-prefixes="s"
  version = "1.0">

<s:init>
  (display "SCHEME: Initialization")
  (define greeting "SCHEME: Hello from scheme.xsl!")
  (newline)
</s:init>

<x:template match="/">
  <x>
    <s:scheme>
      (display greeting)
      (newline)
    </s:scheme>
  </x>
</x:template>

</x:stylesheet>