2012-01-16 12 views
1

xmlTextReaderPtrから構築しようとしています。私の最終的なプログラムでは、I did in javaのような大きなXMLファイルからxsltを使用して小さなDOMツリーを処理するために使用されます。名前空間/接頭辞を使用する適切な方法を見つけることができません(どのように要素と属性を作成する必要がありますか)。ここには非常に基本的なCコードがあります。私はストリームからDOMを構築しており、DOMをダンプします。名前空間/接頭辞を処理するためにコードを変更する方法どうもありがとう !libxml:xmlTextReaderPtrからDOMツリーを構築し、名前空間を扱う

#include <stdio.h> 
#include <libxml/parser.h> 
#include <libxml/tree.h> 
#include <libxml/xmlreader.h> 


/* dump XML node */ 
static void print_element_names(xmlNode * a_node) 
    { 
     xmlNode *cur_node = NULL; 

     for (cur_node = a_node; cur_node; cur_node = xmlNextElementSibling(cur_node)) 
     { 
     if (cur_node->type == XML_ELEMENT_NODE) 
      { 
      xmlAttrPtr attr; 
       printf("node type: Element, name: %s", cur_node->name); 
      if(cur_node->ns!=0 && cur_node->ns->href!=0) printf(" with namespace: %s", cur_node->ns->href); 
      printf("\n"); 
      for(attr = cur_node->properties; NULL != attr; attr = attr->next) 
       { 
       xmlChar* v=xmlGetProp(cur_node,attr->name); 
       printf(" @%s=%s ", attr->name,v); 
       xmlFree(v); 
       } 

      } 

     print_element_names(cur_node->children); 
     } 
    } 


int main(int argc,char** argv) 
    { 
    LIBXML_TEST_VERSION; 
    xmlTextReaderPtr reader; 
    xmlDocPtr doc = NULL; 
    xmlNodePtr current=NULL; 
    xmlNsPtr ns=NULL; 
    /* read from stdin */ 
    reader=xmlReaderForFd(fileno(stdin),0,"UTF-8",0); 


    for(;;) 
     { 
     int nodeType; 
     int ret = xmlTextReaderRead(reader); 
     if(ret<=0) break; 
     nodeType=xmlTextReaderNodeType(reader); 

     switch(nodeType) 
      { 
      case XML_READER_TYPE_ELEMENT: 
       { 
       xmlNsPtr ns=0; 
       xmlNodePtr node; 
       if(doc==NULL) 
        { 
        doc=xmlNewDoc(BAD_CAST "1.0"); 
        } 
       if(xmlTextReaderConstNamespaceUri(reader)!=0) 
        { 
        /** how should I handle the attributes' namespaces & prefix here ? */ 
        xmlNsPtr ns=xmlSearchNs(doc,current,xmlTextReaderConstNamespaceUri(reader)); 
        node=xmlNewNode(ns, xmlTextReaderConstName(reader)); 
        if(ns==0) 
         { 
         ns=xmlNewNs(node, 
          xmlTextReaderConstPrefix(reader), 
          xmlTextReaderConstNamespaceUri(reader) 
          ); 
         } 
        } 
       else 
        { 
        node=xmlNewNode(0, xmlTextReaderConstName(reader)); 
        } 

       if(current==NULL) 
        { 
        xmlDocSetRootElement(doc,node); 
        } 
       else 
        { 

        xmlAddChild(current,node); 
        } 

       current=node; 

       if(xmlTextReaderIsEmptyElement(reader)) 
        { 
        current= current->parent; 
        } 


       if(xmlTextReaderHasAttributes(reader)) 
        { 
        int i; 
        int n_att=xmlTextReaderAttributeCount(reader); 
        for(i=0;i< n_att;++i) 
        { 
        const xmlChar* k; 
        xmlChar* v; 
        xmlTextReaderMoveToAttributeNo(reader,i); 
        k = xmlTextReaderConstName(reader); 
        v = xmlTextReaderValue(reader); 
        /** how should I handle the attributes' namespaces & prefix here ? */ 
        xmlNewProp(node,k, v); 
        xmlFree(v); 
        } 
        xmlTextReaderMoveToElement(reader); 
        } 

       break; 
       } 
      case XML_READER_TYPE_END_ELEMENT: 
       { 
       current= current->parent; 
       break; 
       } 
      case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: 
      case XML_READER_TYPE_TEXT: 
       { 
       const xmlChar* v = xmlTextReaderConstValue(reader); 
       xmlNodePtr node= xmlNewDocText(doc,v); 
       xmlAddChild(current,node); 
       break; 
       } 
      default: 
       { 
       fprintf(stderr,"Ignoring node Type %d\n",nodeType); 
       break; 
       } 
      } 
     } 
    if(doc!=NULL) 
     { 
     print_element_names(xmlDocGetRootElement(doc)); 
     xmlDocDump(stderr,doc); 
     xmlFreeDoc(doc); 
     } 
    xmlFreeTextReader(reader); 
    xmlCleanupParser(); 
    xmlMemoryDump(); 
    return 0; 
    } 

、ここで私のテストファイルです:

<?xml version="1.0"?> 
<a xmlns="http://urn1.org" xmlns:ns1="http://urn2.org" ns1:test="ok">azdazd 
    <b xmlns:ns2="http://urn3.org" xmlns:ns3="http://urn4.org" ns3:test="OK"/> 
    azd 
    <ns1:b test="ok"/> 
    xaz 
</a> 

多くのおかげで、

答えて

1

[OK]を、私は私のerrosを見つけたし、どのようにAPIを使用します。コードは次のとおりです。

#include <stdio.h> 
#include <libxml/parser.h> 
#include <libxml/tree.h> 
#include <libxml/xmlreader.h> 

#define WHERE fprintf(stderr,"[DEBUG]line:%d\n",__LINE__) 

/* dump XML node */ 
static void print_element_names(xmlNode * a_node) 
    { 
     xmlNode *cur_node = NULL; 

     for (cur_node = a_node; cur_node; cur_node = xmlNextElementSibling(cur_node)) 
     { 
     if (cur_node->type == XML_ELEMENT_NODE) 
      { 
      xmlAttrPtr attr; 
      printf("node type: Element, name: %s", cur_node->name); 
      xmlNsPtr ns=cur_node->nsDef; 
      while(ns!=0) 
       { 
       printf(" with namespace: %s %p\n", ns->href,ns->prefix); 
       ns=ns->next; 
       } 

      printf("\n"); 
      for(attr = cur_node->properties; NULL != attr; attr = attr->next) 
       { 
       xmlChar* v=xmlGetProp(cur_node,attr->name); 

     if(attr->ns!=0) 
      { 
      printf(" with namespace: %s %p\n", attr->ns->href,attr->ns->prefix); 

      } 
       printf(" @%s=%s ", attr->name,v); 
       xmlFree(v); 
       } 
     printf("\n"); 
      } 

     print_element_names(cur_node->children); 
     } 
    } 


int main(int argc,char** argv) 
    { 
    LIBXML_TEST_VERSION; 
    xmlTextReaderPtr reader; 
    xmlDocPtr doc = NULL; 
    xmlNodePtr current=NULL; 
    /* read from stdin */ 
    reader=xmlReaderForFd(fileno(stdin),0,"UTF-8",0); 


    for(;;) 
     { 
     int nodeType; 
     int ret = xmlTextReaderRead(reader); 
     if(ret<=0) break; 
     nodeType=xmlTextReaderNodeType(reader); 

     switch(nodeType) 
      { 
      case XML_READER_TYPE_ELEMENT: 
       { 
       xmlNsPtr ns=0; 
       xmlNodePtr node; 
       if(doc==NULL) 
        { 
        doc=xmlNewDoc(BAD_CAST "1.0"); 
        } 
       if(xmlTextReaderConstNamespaceUri(reader)!=0) 
        { 
        xmlNsPtr ns=xmlSearchNs(doc,current,xmlTextReaderConstNamespaceUri(reader)); 
        node=xmlNewNode(ns, xmlTextReaderConstName(reader)); 
        if(ns==0) 
         { 
         WHERE; 
         ns=xmlNewNs(node, 
          xmlTextReaderConstNamespaceUri(reader), 
          xmlTextReaderConstPrefix(reader) 
          ); 
         } 
        } 
       else 
        { 
        node=xmlNewNode(0, xmlTextReaderConstName(reader)); 
        } 

       if(current==NULL) 
        { 
        xmlDocSetRootElement(doc,node); 
        } 
       else 
        { 

        xmlAddChild(current,node); 
        } 

       current=node; 




       if(xmlTextReaderHasAttributes(reader)) 
        { 
        int i; 
        int n_att=xmlTextReaderAttributeCount(reader); 
        for(i=0;i< n_att;++i) 
        { 
        const xmlChar* k; 
        xmlChar* v; 
        xmlTextReaderMoveToAttributeNo(reader,i); 
        k = xmlTextReaderConstName(reader); 
        v = xmlTextReaderValue(reader); 
        if(xmlTextReaderConstNamespaceUri(reader)!=0) 
         { 
         if(!xmlStrEqual(xmlTextReaderConstNamespaceUri(reader),BAD_CAST "http://www.w3.org/2000/xmlns/")) 
         { 
        xmlNsPtr ns=xmlSearchNs(doc,current,xmlTextReaderConstNamespaceUri(reader)); 
         if(ns==0) 
         { 
         ns=xmlNewNs(node, 
          xmlTextReaderConstNamespaceUri(reader), 
          xmlTextReaderConstPrefix(reader) 
          ); 
         } 
        xmlNewNsProp(current,ns, 
         xmlTextReaderConstLocalName(reader) 
         , 
         v); 
        } 
         } 
        else 
         { 
         xmlNewProp(current,k, v); 
         } 


        xmlFree(v); 
        } 
        xmlTextReaderMoveToElement(reader); 
        } 
     if(xmlTextReaderIsEmptyElement(reader)) 
        { 
        current= current->parent; 
        } 
       break; 
       } 
      case XML_READER_TYPE_END_ELEMENT: 
       { 
       current= current->parent; 
       break; 
       } 
      case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: 
      case XML_READER_TYPE_TEXT: 
       { 
       const xmlChar* v = xmlTextReaderConstValue(reader); 
       xmlNodePtr node= xmlNewDocText(doc,v); 
       xmlAddChild(current,node); 
       break; 
       } 
      default: 
       { 
       fprintf(stderr,"Ignoring node Type %d\n",nodeType); 
       break; 
       } 
      } 
     } 
    if(doc!=NULL) 
     { 
     print_element_names(xmlDocGetRootElement(doc)); 
     xmlDocDump(stderr,doc); 
     xmlFreeDoc(doc); 
     } 
    xmlFreeTextReader(reader); 
    xmlCleanupParser(); 
    xmlMemoryDump(); 
    return 0; 
    } 
関連する問題