Rev 7747 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
<html><head><title>FAQ for the XML package in R/S-Plus</title></head><body><h1>FAQ for the XML package in R/S-Plus</h1><dl><dt><li> I have compiled the package from source and everything goesfine, but when I try to load it, I get an error about an"undefined symbol xmlOutputBufferCreateBuffer". What's the problem?<dd>The most obvious explanation is that you are <i>compiling</i> againstone version of libxml2 but <i>loading</i> another.Here is the explanation I gave to several people.<div style="border: solid 1px; background-color: lightgrey; padding: 2pt">That particular routine is either "borrowed"from libxml2.so or if not available from that, a compiledcopy I added to the XML source is used.So it looks like the configuration is smart enough notto compile the one we provide because xmlOutputBufferCreateBuffer()is available in libxml2-2.6.32, but then it fails to find itat load time.<p/>So the first thing that comes to mind is that there is some inconsistencybetween your compile/link configuration and your run-time load configuration.Is it possible that you have an older version of libxml2...so somewhereon your system that is being loaded at run timeTry the shell command<pre>R CMD ldd <wherever XML is installed>/libs/XML.so</pre>and see where it thinks libxml2 is. Hopefully it willlist it and we might see that it is /usr/lib/libxml2.soand that you are compiling against a version in/usr/local/lib/.If that is the case, you would need to change your personal setting for<b>LD_LIBRARY_PATH</b>or add /usr/local/lib to /etc/ld.so.conf file at a system level.</div><dt><li> How do I create my own XML content from within Rand not just parse other people's XML documents?<dd>There are several facilities for doing this in the XML package.Basically you will be creating a tree, a hierarchical collectionof XML nodes.So you need to be able to create the nodes and then arrange theminto this hierarachical structure.You can create all the nodes and then do the tree constructionbut it is typically easier to create the nodes and specifyits parent during the creation.The XML package provides low-level functionsfor creating the nodes andseveral functions which provide a higher level interfacethat try to facilitate adding nodes to a 'current' pointin the tree. These manage the notion of 'current' for you.These functions share a very similar interface and soit is easy to switch from one to the other. They differin how they represent the tree which can be complicatedin R since there are no references/pointers.<p/>The approach I prefer is the <code>xmlTree()</code>function.This uses the low-level node creation functions(e.g. newXMLNode, newXMLComment, newXMLPINode, etc.)but also allows us to manage a stack of "open" nodesand a default namespace prefix.New nodes are by default added to the most recent"open" node, i.e. that node acts as the parent for new nodes.<p/><dt><li> Doesn't the use of internal nodes such as with <codeclass="rfunc">xmlTree()</code> mean that we cannot store thetree across R sessions since they are external pointers to C datastructures in memory.<dd> Well, yes and no. We cannot use R's regular serializationto RDA files of the variables holding the tree or the individualnodes. But we can easily create a text representation from theinternal nodes by dumping the tree, either to a file or acharacter vector of length 1, and then we can restorethat XML tree by parsing it again:<pre>tt = xmlTree("top")tt$addTag("b", "Some text")save(saveXML(tt), file = "tt.rda")load("tt.rda")tt = xmlTreeParse(tt, asText = TRUE, useInternal = TRUE)</pre>We don't get back the XMLInternalDOM with information about opennodes, etc. from which we could continue to add nodes.But we do get back the exact tree.<p/>We can also convert the nodes from internal nodes toregular R base nodes.And from that<dt><li> My XML document has attributes that have a namespaceprefix (e.g.<code><b><node mine:foo="abc" /></b></code>)When I parse this document into S, the namespace prefixon the attribute is dropped. Why and how can I fix it?<dd>The first thing to do isuse a value of <code>TRUE</code> for the <code>addAttributeNamespaces</code>argument in the call to <code>xmlTreeParse</code>.<br>The next thing is to ensure that the namespace(<code>mine</code>, in our example)is defined in the document.In other words, there must be be an<code>xmlns:mine="<i>some url</i>"</code>attribute in some node before or in the nodethat is being processed.If no definition for the namespace is in the document,the libxml parser drops the prefix on the attribute.<br>The same applies to namespaces for node names, and not justattributes.<dt><li> <font class="question">I define a method in the closure, but itnever gets called.</font><dd> The most likely cause is that you omitted to add it to the listof functions returned by the closure. Another possibility isthat you have mis-spelled the name of the method. The matchingis case-sensitive and exact.If the function corresponds to a particular XML element name,check whether the value of the argument <code>useTagName</code> is T,and also that there really is a tag with this name in thedocument.Again, the case is important.<dt><li><font class="question">When I compile the source code, I getlots of warning messages such as<pre>"RSDTD.c", line 110: warning: argument #2 is incompatible with prototype:prototype: pointer to const uchar : "unknown", line 0argument : pointer to const char</pre></font><dd> This is because the XML libraries work on unsigned charactersfor UniCode. The R and S facilities do not.I am not yet certain which direction to adapt things for thispackage. The warnings are typically harmless.<dt><li> <font class="question">When I compile the chapter forSplus5/S4, I get warning messages about SET_CLASS being redefined.</font><dd> This is ok, in this situation. The warning is left there toremind people that there are some games being played and thatif there are problems, to consider these warnings.The SET_CLASS macro being redefined is a local version for S3/Rstyle classes. The one in the Splus5/S4 header files is for theS4 style classes.<dt><li> <font class="question">On which platfforms does it compile?</font><dd> I have used gcc on both Linux (RedHat 6.1) (egcs-2.91.66)and Solaris (gcc-2.7.2.3), and the Sun compilers, cc 4.2 onSolaris 2.6/SunOS 5.6 and cc 5.0 on Solaris 2.7/SunOS 5.7.</dl><dl><dt><li><font class="question">I can't seem to use conditional DTDsegments via the IGNORE/INCLUDE mechanism.</font><dd> Libxml doesn't support this. Perhaps we will add code for this.<p>Daneil Veillard might add this.<dt><li> <font class="question">When I read a relatively simple tree inSplus5 and print it to the terminal/console, I get an errorabout nested expressions exceeding the limit of 256.</font><dd> The simple fix is to set the value of the<code>expressions</code>option to a value larger than 256.<pre>options(expressions=1000)</pre>The main cause of this is thatS and R are programming languages not specialized for handlingtrees.(They are functional languages and have no facilities forpointers or references as in C or Java.)<dt><li> <font class="question">I get errors when using parameterentities in DTDs?</font><dd>This was true in version 1.7.3 and 1.8.2 oflibxml. Thanks to Daneil Veillard for fixingthis quickly when I pointed it out.<p>Parameters are allowed, but the libxml parsing library is fussyabout white-space, etc.The following is is ok<pre><!ELEMENT legend (%PlotPrimitives;)* ></pre>but<pre><!ELEMENT legend (%PlotPrimitives; )* ></pre>is not. The extra space preceeding the <code>)</code>causes an error in the parser something like<pre>1: XML Parsing Error: ../Histogram.dtd:80: xmlParseElementChildrenContentDecl : ',' '|' or ')' expected2: XML Parsing Error: ../Histogram.dtd:80: xmlParseElementChildrenContentDecl : ',' expected3: XML Parsing Error: ../Histogram.dtd:80: xmlParseElementDecl: expected '>' at the end4: XML Parsing Error: ../Histogram.dtd:80: Extra content at the end of the document</pre>This can be fixed by adding a call to SKIP_BLANKS at the end ofthe loop <code>while(CUR!= ')' { ... } </code> in the routine<code>xmlParseElementChildrenContentDecl()</code> in parser.cThe problem lies in the transition between the different inputbuffers introduced by the entity expansion.<dt><li> I am trying to use XPath and getNodeSet(). But I am notmatching any nodes.<dd>If you are certain that the XPath expression should match what youwant, then it is probably a matter of namespaces.If the document in which you are trying to find the nodes has adefault namespace (at the top-level node or a sub-nodeinvolved in your match), then you have to explicitly identifythe namespace. Unfortunately, XPath doesn't use the defaultnamespace of the target document, but requires the namespaceto be explicitly mentioned in the XPath expression.<p/>For example, suppose we have a document that looks like<pre><![CDATA[<doc xmlns="http://www.omegahat.net"><topic><title>My Title</title></topic></doc>]]></pre>and we want to use an XPath expression to find the title node.We might think that <code>"/doc/topic/title"</code>would do the trick. But in fact, we need<pre>/ns:doc/ns:topci/ns:title</pre>And then we need to map ns to the URI "http://www.omegahat.net".We do this in a call to getNodeSet() as<pre>getNodeSet(doc, "/ns:doc/ns:topci/ns:title", c(ns = "http://www.omegahat.net"))</pre><p/>As a simplification, getNodeSet() will create the map betweenthe prefix and the URI of the default namespace of the XMLdocument if you specify a single string with no name as thevalueof the <code>namespaces</code> argument, e.g.<pre>getNodeSet(doc, "/ns:doc/ns:topci/ns:title", "ns")</pre><p/>There are some additional comments <ahref="http://plasmasturm.org/log/259/">here</a>.<dt><li> There is an table of data in HTML that I want to read into Ras a data frame. How can I do it?<dd>Well, it is relatively easy, although the technology underlyingit is quite powerful and somewhat complex in the general case.There is a <a href="htmlTables.xml">document describing the approach(es)</a><dt><li> I have a "large" XML file. Can I use DOM parsing or do I haveto use SAX style parsing via the more complex xmlEventParse().<dd> Well, I was given a 70 Mb XML file (which when compressed is6MB) and after uncompressing the file, I can read it into Rvia <code class="r">xmlTreeParse(, useInternalTrue =TRUE)</code>This file contained 2,895,409 nodes(<code class="r">length(getNodeSet(z, "//*"))</code>)This took 9.4 seconds on Intel MacBook Pro with a 2.33Ghz Dualprocessor and 3G of RAM, and on a machine with dual core 64bit AMD,it took 20 seconds.To find the nodes of interest took 8.9 seconds on the Mac, and(apparently) 1.1 seconds on the AMD.<dt><li> I want to include one document inside another. How can I do this?<dd> Firstly, you want to look into XInclude.When processing the document in R, use <code>xinclude = TRUE</code>, whichis the default, in calls to xmlTreeParse().<dt><li> I want to use XInclude to include part of the samedocument. I can't figure out how to do it. Any ideas?<dd>Yes. Use<pre><xi:include xpointer="xpointer(//mynode)"/></pre>adapting that to what you want.Note that the attribute is named xpointer.There is no href so the XInclude defaults to this documentand the expression for the xpointer attributeuses the function xpointer. This is not element.<dt><li> When I parse HTML content, what does the &nbsp; entity turn into?<dd>This turns into the Unicode character U+00A0, or in R "\u00A0".</dl><hr><address><a href="http://www.stat.ucdavis.edu/~duncan">Duncan Temple Lang</a><a href=mailto:duncan@wald.ucdavis.edu><duncan@wald.ucdavis.edu></a></address><!-- hhmts start -->Last modified: Fri Dec 14 04:29:02 PST 2012<!-- hhmts end --></body> </html>