2016-11-23 3 views
0

나는 다음과 같은 유효한 XML이 :xml-tag는 두 개의 네임 스페이스를 사용할 수 있습니까? 아니면 libxml2 버그입니까?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
    <aaa xmlns:de="http://www.dolby.com/dcinema/ws/smi/v11/SPL" atr="abc" xmlns:fe="http://somewhere"> 
    some text 
    <de:bbb atr1="abb" atr2="baa" >aaa</de:bbb> 
    <de:ccc>aaa</de:ccc> 
    <fe:ddd>bbb</fe:ddd> 
    some more text 
    </aaa> 

그리고 다음과 같은 C 코드 :

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

char xml_data[] = { 
    "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" 
    " <aaa xmlns:de=\"http://www.dolby.com/dcinema/ws/smi/v11/SPL\" " 
    "  atr=\"abc\"" 
    "  xmlns:fe=\"http://somewhere\">\n" 
    " some text\n" 
    " <de:bbb atr1=\"abb\" atr2=\"baa\" >aaa</de:bbb>\n" 
    " <de:ccc>aaa</de:ccc>\n" 
    " <fe:ddd>bbb</fe:ddd>\n" 
    " some more text\n" 
    " </aaa>" 
}; 

void printns(xmlNsPtr ns, int deep, char * marker) 
{ 
    while (ns) 
    { 
     printf("%*c%s+%s\n", deep * 5 + 1, ' ', marker, ns->prefix); 
     ns = ns->next; 
    } 
} 

void printelem(xmlNodePtr ptr, int deep) 
{ 
    printf("%*c%s\n", deep * 5, ' ', ptr->name); 
    if (ptr->type == XML_ELEMENT_NODE) 
    { 
     printns(ptr->nsDef, deep, "d"); 
     printns(ptr->ns, deep, "u"); 
    } 

    if (ptr->xmlChildrenNode) printelem(ptr->xmlChildrenNode, deep+1); 

    if (ptr->next) printelem(ptr->next, deep); 
} 

int main(void) 
{ 
    LIBXML_TEST_VERSION 
    xmlInitParser(); 

    xmlDocPtr doc; 
    doc = xmlReadDoc(BAD_CAST xml_data, NULL, NULL, XML_PARSE_NOBLANKS); 

    printelem(doc->xmlChildrenNode, 1); 

    xmlFreeDoc(doc); 
} 

이 다음과 같은 출력이 생성을 :

aaa 
    d+de 
    d+fe 
     text 
     bbb 
     u+de 
     u+fe 
      text 
     text 
     ccc 
     u+de 
     u+fe 
      text 
     text 
     ddd 
     u+fe 
      text 
     text 

보시다시피가, libxml2를 말한다 bbb와 ccc는 ddd가 예상대로 하나의 네임 스페이스를 가질 때 한 번에 두 개의 네임 스페이스를 갖습니다. 이것이 나에게 알려지지 않았거나 libxml2 버그 인 xml-standart 규칙인가?

+0

XML이 유효하지 않다고 생각합니다. 그것은 잘 형성되어 있습니다. –

+0

[MCVE]에게 코드를 제공해 주시겠습니까? 그리고 사용중인 정확한 버전 번호. –

+0

제공된 xml은 standart 및 http://www.xmlvalidation.com/과 같은 유효성 검사기에서 절대적으로 유효합니다. 최대한 빨리 MCV를 제공하려고합니다. –

답변

1

XML 요소의 이름에는 분명히 단일 네임 스페이스 만있을 수 있습니다. 따라서 struct _xmlNode에있는 ns 회원을 링크 된 목록으로 생각하면 안됩니다. 실제로는 조상 요소의 nsDef 항목을 가리 킵니다. next 포인터는 nsDef을 반복 할 때만 사용하십시오. 당신은 또한 xmlNs 구조체의 주소를 표시하는 printnsprintf 문을 변경하는 경우

printf("%*c%s+%s [%p]\n", deep * 5 + 1, ' ', marker, ns->prefix, 
     (void*)ns); 

출력은 ns 항상 요소의 올바른 xmlNs를 가리키는 것을

aaa 
    d+de [0x9e9aff0] 
    d+fe [0x9e9b1a0] 
     text 
     bbb 
     u+de [0x9e9aff0] // same as first entry in nsDef of aaa 
     u+fe [0x9e9b1a0] // should be ignored 
      text 
     text 
     ccc 
     u+de [0x9e9aff0] // same as first entry in nsDef of aaa 
     u+fe [0x9e9b1a0] // should be ignored 
      text 
     text 
     ddd 
     u+fe [0x9e9b1a0] // same as second entry in nsDef of aaa 
      text 
     text 

참고가된다.

+0

감사합니다. 나는 처음 것만 받아야한다고 생각했으나 그것을 확인하기 위해 누군가를 필요로했다. –