Writing API で XMLの書き出し

Libxml2 の Writing API っていうのは、 XML を頭から出力するときに役立つ API

#include <stdio.h>
#include <string.h>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>

#define MY_ENCODING "UTF-8"

/*****************************************************************************************/
/* output                                                                                */
/* ------                                                                                */
/* <?xml version="1.0" encoding="UTF-8"?>           : xmlTextWriterStartDocument &       */
/*                                                  :   xmlTextWriterWriteAttribute      */
/* <EXAMPLE>                                        : xmlTextWriterStartElement          */
/*   <!--This is a comment-->                       : xmlTextWriterWriteComment          */
/*   <ORDER version="1.0" xml:lang="de">            : xmlTextWriterStartElement  &       */
/*                                                  :   xmlTextWriterWriteAttribute      */
/*     <!--This is formatted comment-->             : xmlTextWriterWriteFormatComment    */
/*     <ENTRY>                                      : xmlTextWriterStartElement          */
/*       <ARTICLE>&lt;Test&gt;</ARTICLE>            : xmlTextWriterWriteElement          */
/*       <ENTRY_NO>Formatted Element 0010/ENTRY_NO> : xmlTextWriterWriteFormatElement    */
/*     </ENTRY>                                     : xmlTextWriterEndElement            */
/*     <FOOT>Formatted string 1</FOOT>              : xmlTextWriterStartElement &        */
/*                                                  :   xmlTextWriterWriteFormatString & */
/*                                                  :   xmlTextWriterEndElement          */
/*   </ORDER>                                       : xmlTextWriterEndDocument           */
/* </EXAMPLE>                                       :                                    */
/*****************************************************************************************/

void testXmlwriterFilename(const char *uri)
{
    int               ret;
    xmlTextWriterPtr  writer;

    /* Create a new XmlWriter for uri, with no compression. */
    writer = xmlNewTextWriterFilename(uri, 0);
    if (writer == NULL) {
        fprintf(stderr, "Error creating the xml writer\n");
        goto LAST;
    }

    /* Start the document with the xml default for the version,
     * encoding MY_ENCODING and the default for the standalone
     * declaration. */
    ret = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterStartDocument\n");
        goto LAST;
    }

    /* Start an element named "EXAMPLE". Since thist is the first
     * element, this will be the root element of the document. */
    ret = xmlTextWriterStartElement(writer, BAD_CAST "EXAMPLE");
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterStartElement\n");
        goto LAST;
    }

    /* Write a comment as child of EXAMPLE */
    ret = xmlTextWriterWriteComment(writer, "This is a comment");
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterWriteComment\n");
        goto LAST;
    }

    /* Start an element named "ORDER" as child of EXAMPLE. */
    ret = xmlTextWriterStartElement(writer, BAD_CAST "ORDER");
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterStartElement\n");
        goto LAST;
    }

    /* Add an attribute with name "version" and value "1.0" to ORDER. */
    ret = xmlTextWriterWriteAttribute(writer, BAD_CAST "version",
                                     BAD_CAST "1.0");
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterWriteAttribute\n");
        goto LAST;
    }

    /* Add an attribute with name "xml:lang" and value "de" to ORDER. */
    ret = xmlTextWriterWriteAttribute(writer, BAD_CAST "xml:lang",
                                     BAD_CAST "de");
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterWriteAttribute\n");
        goto LAST;
    }

    /* Write a comment as child of ORDER */
    ret = xmlTextWriterWriteFormatComment(writer,
                                          "This is formatted comment",
                                          "%d", 1);
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterWriteFormatComment\n");
        goto LAST;
    }

    /* Start an element named "ENTRY" */
    ret = xmlTextWriterStartElement(writer, BAD_CAST "ENTRY");
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterStartElement\n");
        goto LAST;
    }

    /* Write an element named "ARTICLE" as child of ENTRY. */
    ret = xmlTextWriterWriteElement(writer, BAD_CAST "ARTICLE",
                                   BAD_CAST "<Test>");
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterWriteElement\n");
        goto LAST;
    }

    /* Write an element named "ENTRY_NO" as child of ENTRY. */
    ret = xmlTextWriterWriteFormatElement(writer,
                                          BAD_CAST "ENTRY_NO",
                                          "Formatted element %04d",
                                         10);
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterWriteFormatElement\n");
        goto LAST;
    }

    /* Close the element named ENTRY. */
    ret = xmlTextWriterEndElement(writer);
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterEndElement\n");
        goto LAST;
    }

    /* Start an element named "FOOT" */
    ret = xmlTextWriterStartElement(writer, BAD_CAST "FOOT");
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterStartElement\n");
        goto LAST;
    }

    /* Write Text */
    ret = xmlTextWriterWriteFormatString(writer, "Formatted string %d", 1);
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterWriteFormatString\n");
        goto LAST;
    }

    /* Close the element named FOOT. */
    ret = xmlTextWriterEndElement(writer);
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterEndElement\n");
        goto LAST;
    }

    /* Here we could close the elements ORDER and EXAMPLE using the
     * function xmlTextWriterEndElement */
    ret = xmlTextWriterEndDocument(writer);
    if (ret < 0) {
        fprintf(stderr, "Error at xmlTextWriterEndDocument\n");
        goto LAST;
    }

 LAST:
    xmlFreeTextWriter(writer);
}

int main(int argc, char **argv)
{
    char *output_file;
    int   ret;

    if (argc != 2) {
        return 1;
    }

    output_file = argv[1];

    LIBXML_TEST_VERSION;

    testXmlwriterFilename(output_file);

    xmlCleanupParser();

    return;
}

出力ファイル。素の状態だと見づらいので、xmllint --formatの出力。

<?xml version="1.0" encoding="UTF-8"?>
<EXAMPLE>
  <!--This is a comment-->
  <ORDER version="1.0" xml:lang="de">
    <!--This is formatted comment-->
    <ENTRY>
      <ARTICLE>&lt;Test&gt;</ARTICLE>
      <ENTRY_NO>Formatted element 0010</ENTRY_NO>
    </ENTRY>
    <FOOT>Formatted string 1</FOOT>
  </ORDER>
</EXAMPLE>