2 * XDR (XML-Data Reduced) -> XSD (XML Schema Document) conversion
4 * Copyright 2010 Adam Martinson for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <libxml/tree.h>
24 #include "wine/debug.h"
26 /* Both XDR and XSD are valid XML
27 * We just convert the doc tree, no need for a parser.
30 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
32 static const xmlChar DT_prefix
[] = "dt";
33 static const xmlChar DT_href
[] = "urn:schemas-microsoft-com:datatypes";
34 static const xmlChar XDR_href
[] = "urn:schemas-microsoft-com:xml-data";
35 static const xmlChar XSD_prefix
[] = "xsd";
36 static const xmlChar XSD_href
[] = "http://www.w3.org/2001/XMLSchema";
38 static const xmlChar xs_all
[] = "all";
39 static const xmlChar xs_annotation
[] = "annotation";
40 static const xmlChar xs_any
[] = "any";
41 static const xmlChar xs_anyAttribute
[] = "anyAttribute";
42 static const xmlChar xs_attribute
[] = "attribute";
43 static const xmlChar xs_AttributeType
[] = "AttributeType";
44 static const xmlChar xs_base
[] = "base";
45 static const xmlChar xs_choice
[] = "choice";
46 static const xmlChar xs_complexType
[] = "complexType";
47 static const xmlChar xs_content
[] = "content";
48 static const xmlChar xs_datatype
[] = "datatype";
49 static const xmlChar xs_default
[] = "default";
50 static const xmlChar xs_description
[] = "description";
51 static const xmlChar xs_documentation
[] = "documentation";
52 static const xmlChar xs_element
[] = "element";
53 static const xmlChar xs_ElementType
[] = "ElementType";
54 static const xmlChar xs_eltOnly
[] = "eltOnly";
55 static const xmlChar xs_enumeration
[] = "enumeration";
56 static const xmlChar xs_extension
[] = "extension";
57 static const xmlChar xs_group
[] = "group";
58 static const xmlChar xs_lax
[] = "lax";
59 static const xmlChar xs_length
[] = "length";
60 static const xmlChar xs_many
[] = "many";
61 static const xmlChar xs_maxOccurs
[] = "maxOccurs";
62 static const xmlChar xs_minOccurs
[] = "minOccurs";
63 static const xmlChar xs_mixed
[] = "mixed";
64 static const xmlChar xs_model
[] = "model";
65 static const xmlChar xs_name
[] = "name";
66 static const xmlChar xs_namespace
[] = "namespace";
67 static const xmlChar xs_no
[] = "no";
68 static const xmlChar xs_open
[] = "open";
69 static const xmlChar xs_optional
[] = "optional";
70 static const xmlChar xs_order
[] = "order";
71 static const xmlChar xs_processContents
[] = "processContents";
72 static const xmlChar xs_ref
[] = "ref";
73 static const xmlChar xs_required
[] = "required";
74 static const xmlChar xs_restriction
[] = "restriction";
75 static const xmlChar xs_schema
[] = "schema";
76 static const xmlChar xs_seq
[] = "seq";
77 static const xmlChar xs_sequence
[] = "sequence";
78 static const xmlChar xs_simpleContent
[] = "simpleContent";
79 static const xmlChar xs_simpleType
[] = "simpleType";
80 static const xmlChar xs_strict
[] = "strict";
81 static const xmlChar xs_targetNamespace
[] = "targetNamespace";
82 static const xmlChar xs_textOnly
[] = "textOnly";
83 static const xmlChar xs_true
[] = "true";
84 static const xmlChar xs_type
[] = "type";
85 static const xmlChar xs_unbounded
[] = "unbounded";
86 static const xmlChar xs_use
[] = "use";
87 static const xmlChar xs_value
[] = "value";
88 static const xmlChar xs_values
[] = "values";
89 static const xmlChar xs_xsd_string
[] = "xsd:string";
91 typedef enum _CONTENT_TYPE
99 typedef enum _ORDER_TYPE
106 #define FOREACH_CHILD(node, child) \
107 for (child = node->children; child != NULL; child = child->next) \
108 if (child->type == XML_ELEMENT_NODE)
110 #define FOREACH_ATTR(node, attr) \
111 for (attr = node->properties; attr != NULL; attr = attr->next)
113 #define FOREACH_NS(node, ns) \
114 for (ns = node->nsDef; ns != NULL; ns = ns->next)
116 static inline xmlNodePtr
get_schema(xmlNodePtr node
)
118 return xmlDocGetRootElement(node
->doc
);
121 static inline xmlNodePtr
get_child(xmlNodePtr node
, xmlChar
const* name
)
123 xmlNodePtr child
= NULL
;
126 FOREACH_CHILD(node
, child
)
128 if (xmlStrEqual(child
->name
, name
))
136 static inline xmlNodePtr
get_child_with_attr(xmlNodePtr node
, xmlChar
const* name
,
137 xmlChar
const* attr_ns
, xmlChar
const* attr_name
,
138 xmlChar
const* attr_val
)
143 FOREACH_CHILD(node
, node
)
145 if (xmlStrEqual(node
->name
, name
))
147 str
= (attr_ns
!= NULL
)? xmlGetNsProp(node
, attr_name
, attr_ns
) :
148 xmlGetProp(node
, attr_name
);
151 if (xmlStrEqual(str
, attr_val
))
165 static inline xmlNsPtr
get_dt_ns(xmlNodePtr node
)
169 node
= get_schema(node
);
170 assert(node
!= NULL
);
174 if (xmlStrEqual(ns
->href
, DT_href
))
181 static inline xmlChar
* get_dt_type(xmlNodePtr xdr
)
183 xmlChar
* str
= xmlGetNsProp(xdr
, xs_type
, DT_href
);
186 xmlNodePtr datatype
= get_child(xdr
, xs_datatype
);
188 str
= xmlGetNsProp(datatype
, xs_type
, DT_href
);
193 static inline xmlChar
* get_attr_val(xmlAttrPtr attr
)
195 return xmlNodeGetContent((xmlNodePtr
)attr
);
198 static inline xmlNodePtr
add_any_child(xmlNodePtr parent
, BOOL set_occurs
)
200 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_any
, NULL
);
203 xmlSetProp(child
, xs_minOccurs
, BAD_CAST
"0");
204 xmlSetProp(child
, xs_maxOccurs
, xs_unbounded
);
206 xmlSetProp(child
, xs_processContents
, xs_strict
);
210 static inline xmlNodePtr
add_anyAttribute_child(xmlNodePtr parent
)
212 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_anyAttribute
, NULL
);
213 xmlSetProp(child
, xs_processContents
, xs_lax
);
217 static inline xmlAttrPtr
copy_prop_ignore_ns(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
219 xmlChar
* str
= get_attr_val(xdr_attr
);
220 xmlAttrPtr attr
= xmlSetProp(node
, xdr_attr
->name
, str
);
224 static inline xmlAttrPtr
XDR_A_default(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
226 TRACE("(%p, %p)\n", xdr_attr
, node
);
228 return copy_prop_ignore_ns(xdr_attr
, node
);
231 static inline xmlAttrPtr
XDR_A_dt_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
233 xmlChar
* str
= get_attr_val(xdr_attr
);
236 TRACE("(%p, %p)\n", xdr_attr
, node
);
238 if (xmlStrEqual(str
, xs_enumeration
))
241 attr
= xmlSetNsProp(node
, get_dt_ns(node
), DT_prefix
, str
);
246 static xmlAttrPtr
XDR_A_maxOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
248 xmlChar
* str
= get_attr_val(xdr_attr
);
251 TRACE("(%p, %p)\n", xdr_attr
, node
);
253 if (xmlStrEqual(str
, BAD_CAST
"*"))
254 attr
= xmlSetProp(node
, xs_maxOccurs
, xs_unbounded
);
256 attr
= copy_prop_ignore_ns(xdr_attr
, node
);
262 static inline xmlAttrPtr
XDR_A_minOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
264 TRACE("(%p, %p)\n", xdr_attr
, node
);
266 return copy_prop_ignore_ns(xdr_attr
, node
);
269 static inline xmlAttrPtr
XDR_A_name(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
271 TRACE("(%p, %p)\n", xdr_attr
, node
);
273 return copy_prop_ignore_ns(xdr_attr
, node
);
276 static xmlAttrPtr
XDR_A_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
278 xmlChar
* str
= get_attr_val(xdr_attr
);
279 xmlAttrPtr attr
= xmlSetProp(node
, xs_ref
, str
);
281 TRACE("(%p, %p)\n", xdr_attr
, node
);
287 static xmlAttrPtr
XDR_A_required(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
289 xmlChar
* str
= get_attr_val(xdr_attr
);
292 TRACE("(%p, %p)\n", xdr_attr
, node
);
294 if (xmlStrEqual(str
, xs_no
))
295 attr
= xmlSetProp(node
, xs_use
, xs_optional
);
297 attr
= xmlSetProp(node
, xs_use
, xs_required
);
302 static xmlNodePtr
XDR_E_description(xmlNodePtr xdr
, xmlNodePtr parent
)
304 xmlNodePtr xsd_node
= xmlNewChild(parent
, NULL
, xs_annotation
, NULL
);
307 TRACE("(%p, %p)\n", xdr
, parent
);
309 xmlNewChild(xsd_node
, NULL
, xs_documentation
, xdr
->content
);
311 FOREACH_ATTR(xdr
, xdr_attr
)
313 xmlCopyProp(xsd_node
, xdr_attr
);
318 static xmlNodePtr
XDR_E_AttributeType(xmlNodePtr xdr
, xmlNodePtr parent
)
320 xmlChar
*str
, *type
= get_dt_type(xdr
);
321 xmlNodePtr xsd_node
, xsd_child
, xdr_child
;
324 TRACE("(%p, %p)\n", xdr
, parent
);
326 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
328 if (type
&& xmlStrEqual(type
, xs_enumeration
))
330 xmlChar
*tmp
, *tokBegin
, *tokEnd
= NULL
;
332 xsd_child
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
333 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_restriction
, NULL
);
334 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
336 tokBegin
= str
= xmlGetNsProp(xdr
, xs_values
, DT_href
);
337 while (tokBegin
&& *tokBegin
)
339 while (*tokBegin
&& isspace(*tokBegin
))
342 while (*tokEnd
&& !isspace(*tokEnd
))
344 if (tokEnd
== tokBegin
)
346 xsd_enum
= xmlNewChild(xsd_child
, NULL
, xs_enumeration
, NULL
);
347 tmp
= xmlStrndup(tokBegin
, tokEnd
-tokBegin
);
348 xmlSetProp(xsd_enum
, xs_value
, tmp
);
357 str
= xmlStrdup(DT_prefix
);
358 str
= xmlStrcat(str
, BAD_CAST
":");
359 str
= xmlStrcat(str
, type
);
360 xmlSetProp(xsd_node
, xs_type
, str
);
365 FOREACH_ATTR(xdr
, xdr_attr
)
367 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
368 XDR_A_default(xdr_attr
, xsd_node
);
369 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
370 XDR_A_name(xdr_attr
, xsd_node
);
371 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
372 XDR_A_dt_type(xdr_attr
, xsd_node
);
373 else if (xmlStrEqual(xdr_attr
->name
, xs_values
) && xdr_attr
->ns
== get_dt_ns(xdr
))
374 ; /* already handled */
375 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
376 XDR_A_required(xdr_attr
, xsd_node
);
378 xmlCopyProp(xsd_node
, xdr_attr
);
381 FOREACH_CHILD(xdr
, xdr_child
)
383 if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
384 ; /* already handled */
385 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
386 XDR_E_description(xdr_child
, xsd_node
);
388 FIXME("unexpected child <%s>\n", xdr_child
->name
);
394 static xmlNodePtr
XDR_E_attribute(xmlNodePtr xdr
, xmlNodePtr parent
)
396 xmlChar
* str
= xmlGetProp(xdr
, xs_type
);
397 xmlNodePtr xsd_node
, xdr_child
, xdr_attrType
;
400 TRACE("(%p, %p)\n", xdr
, parent
);
402 xdr_attrType
= get_child_with_attr(xdr
->parent
, xs_AttributeType
, NULL
, xs_name
, str
);
406 xsd_node
= XDR_E_AttributeType(xdr_attrType
, parent
);
408 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
410 FOREACH_ATTR(xdr
, xdr_attr
)
412 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
413 XDR_A_default(xdr_attr
, xsd_node
);
414 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && !xdr_attrType
)
415 XDR_A_type(xdr_attr
, xsd_node
);
416 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
417 XDR_A_required(xdr_attr
, xsd_node
);
419 xmlCopyProp(xsd_node
, xdr_attr
);
422 FOREACH_CHILD(xdr
, xdr_child
)
424 FIXME("unexpected child <%s>\n", xdr_child
->name
);
430 static xmlNodePtr
XDR_E_element(xmlNodePtr xdr
, xmlNodePtr parent
)
432 xmlNodePtr xdr_child
, xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
435 FOREACH_ATTR(xdr
, xdr_attr
)
437 if (xmlStrEqual(xdr_attr
->name
, xs_type
))
438 XDR_A_type(xdr_attr
, xsd_node
);
439 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
440 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
441 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
442 XDR_A_minOccurs(xdr_attr
, xsd_node
);
444 xmlCopyProp(xsd_node
, xdr_attr
);
447 FOREACH_CHILD(xdr
, xdr_child
)
449 FIXME("unexpected child <%s>\n", xdr_child
->name
);
455 static xmlNodePtr
XDR_E_group(xmlNodePtr xdr
, xmlNodePtr parent
)
457 xmlNodePtr xdr_child
, xsd_node
;
458 xmlChar
* str
= xmlGetProp(xdr
, xs_order
);
461 TRACE("(%p, %p)\n", xdr
, parent
);
463 if (!str
|| xmlStrEqual(str
, xs_seq
))
464 xsd_node
= xmlNewChild(parent
, NULL
, xs_sequence
, NULL
);
465 else if (xmlStrEqual(str
, xs_many
))
466 xsd_node
= xmlNewChild(parent
, NULL
, xs_choice
, NULL
);
468 xsd_node
= xmlNewChild(parent
, NULL
, xs_all
, NULL
);
471 FOREACH_ATTR(xdr
, xdr_attr
)
473 if (xmlStrEqual(xdr_attr
->name
, xs_order
))
474 ; /* already handled */
475 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
477 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
478 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
479 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
480 XDR_A_minOccurs(xdr_attr
, xsd_node
);
482 xmlCopyProp(xsd_node
, xdr_attr
);
485 FOREACH_CHILD(xdr
, xdr_child
)
487 if (xmlStrEqual(xdr_child
->name
, xs_description
))
488 XDR_E_description(xdr_child
, xsd_node
);
489 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
490 XDR_E_element(xdr_child
, xsd_node
);
496 static xmlNodePtr
XDR_E_ElementType(xmlNodePtr xdr
, xmlNodePtr parent
)
498 xmlChar
*str
, *type
= get_dt_type(xdr
);
500 int n_attributes
= 0, n_elements
= 0, n_groups
= 0;
501 CONTENT_TYPE content
;
503 xmlNodePtr xsd_node
, xsd_type
, xsd_child
, xdr_child
;
505 xmlNsPtr dt_ns
= get_dt_ns(parent
);
507 TRACE("(%p, %p)\n", xdr
, parent
);
509 str
= xmlGetProp(xdr
, xs_model
);
510 if (str
&& !xmlStrEqual(str
, xs_open
))
516 content
= CONTENT_TEXTONLY
;
520 str
= xmlGetProp(xdr
, xs_content
);
521 if (!str
|| xmlStrEqual(str
, xs_mixed
))
522 content
= CONTENT_MIXED
;
523 else if (xmlStrEqual(str
, xs_eltOnly
))
524 content
= CONTENT_ELTONLY
;
525 else if (xmlStrEqual(str
, xs_textOnly
))
526 content
= CONTENT_TEXTONLY
;
528 content
= CONTENT_EMPTY
;
532 str
= xmlGetProp(xdr
, xs_order
);
533 if (!str
|| xmlStrEqual(str
, xs_seq
))
537 else if (xmlStrEqual(str
, xs_many
))
548 FOREACH_CHILD(xdr
, xdr_child
)
550 if (xmlStrEqual(xdr_child
->name
, xs_element
))
552 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
554 else if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
558 xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
559 assert(xsd_node
!= NULL
);
563 case CONTENT_ELTONLY
:
566 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
568 if (content
== CONTENT_MIXED
)
569 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
572 xsd_base
= xmlNewChild(xsd_type
, NULL
, xs_sequence
, NULL
);
576 if (is_open
&& n_elements
< 2 && !n_groups
)
577 {/* no specific sequence of elements we need,
578 just has to start with the right one, if any */
579 if ((xdr_child
= get_child(xdr
, xs_element
)))
581 xsd_child
= XDR_E_element(xdr_child
, xsd_base
);
582 xmlUnsetProp(xsd_child
, xs_maxOccurs
);
590 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_sequence
, NULL
);
593 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_choice
, NULL
);
594 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
597 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_all
, NULL
);
601 FOREACH_CHILD(xdr
, xdr_child
)
603 if (xmlStrEqual(xdr_child
->name
, xs_element
))
604 XDR_E_element(xdr_child
, xsd_child
);
605 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
606 XDR_E_group(xdr_child
, xsd_child
);
612 FOREACH_CHILD(xdr
, xdr_child
)
614 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
615 XDR_E_attribute(xdr_child
, xsd_type
);
621 add_any_child(xsd_base
, TRUE
);
622 add_anyAttribute_child(xsd_type
);
626 case CONTENT_TEXTONLY
:
630 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
633 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
634 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
635 str
= xmlStrdup(DT_prefix
);
636 str
= xmlStrcat(str
, BAD_CAST
":");
637 str
= xmlStrcat(str
, type
);
638 xmlSetProp(xsd_child
, xs_base
, str
);
640 assert(dt_ns
!= NULL
);
641 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
645 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
646 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_choice
, NULL
);
647 xmlSetProp(xsd_child
, xs_minOccurs
, BAD_CAST
"0");
648 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
649 xsd_child
= add_any_child(xsd_child
, FALSE
);
650 xmlSetProp(xsd_child
, xs_namespace
, BAD_CAST
"##other");
651 xsd_child
= xsd_type
;
655 FOREACH_CHILD(xdr
, xdr_child
)
657 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
658 XDR_E_attribute(xdr_child
, xsd_child
);
661 xmlNewChild(xsd_child
, NULL
, xs_anyAttribute
, NULL
);
663 else if (!n_attributes
)
667 str
= xmlStrdup(DT_prefix
);
668 str
= xmlStrcat(str
, BAD_CAST
":");
669 str
= xmlStrcat(str
, type
);
670 xmlSetProp(xsd_node
, xs_type
, str
);
673 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
677 xmlSetProp(xsd_node
, xs_type
, xs_xsd_string
);
682 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
683 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
684 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
685 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
687 FOREACH_CHILD(xdr
, xdr_child
)
689 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
690 XDR_E_attribute(xdr_child
, xsd_child
);
695 case CONTENT_EMPTY
: /* not allowed with model="open" */
699 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
701 FOREACH_CHILD(xdr
, xdr_child
)
703 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
704 XDR_E_attribute(xdr_child
, xsd_type
);
709 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
710 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_restriction
, NULL
);
711 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
712 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_length
, NULL
);
713 xmlSetProp(xsd_child
, xs_value
, BAD_CAST
"0");
720 FOREACH_ATTR(xdr
, xdr_attr
)
722 if (xmlStrEqual(xdr_attr
->name
, xs_content
))
723 ; /* already handled */
724 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
725 XDR_A_name(xdr_attr
, xsd_node
);
726 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
727 XDR_A_dt_type(xdr_attr
, xsd_node
);
728 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
729 ; /* already handled */
730 else if (xmlStrEqual(xdr_attr
->name
, xs_order
))
731 ; /* already handled */
733 xmlCopyProp(xsd_node
, xdr_attr
);
737 FOREACH_CHILD(xdr
, xdr_child
)
739 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
740 ; /* already handled */
741 else if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
742 ; /* handled through XDR_E_attribute when parent is not <Schema> */
743 else if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
744 ; /* already handled */
745 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
746 XDR_E_description(xdr_child
, xsd_node
);
747 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
748 ; /* already handled */
749 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
750 ; /* already handled */
752 FIXME("unexpected child <%s>\n", xdr_child
->name
);
758 static xmlNodePtr
XDR_E_Schema(xmlNodePtr xdr
, xmlNodePtr parent
, xmlChar
const* nsURI
)
760 xmlNodePtr xsd_node
, xdr_child
;
764 TRACE("(%p, %p)\n", xdr
, parent
);
766 xsd_node
= xmlNewDocNode((xmlDocPtr
)parent
, NULL
, xs_schema
, NULL
);
767 xmlDocSetRootElement((xmlDocPtr
)parent
, xsd_node
);
768 assert(xsd_node
!= NULL
);
770 if (nsURI
&& *nsURI
) xmlNewNs(xsd_node
, nsURI
, NULL
);
771 ns
= xmlNewNs(xsd_node
, XSD_href
, XSD_prefix
);
774 xmlSetNs(xsd_node
, ns
);
776 if (nsURI
&& *nsURI
) xmlSetProp(xsd_node
, xs_targetNamespace
, nsURI
);
778 FOREACH_NS(xdr
, xdr_ns
)
780 /* TODO: special handling for dt namespace? */
781 assert(xdr_ns
->href
!= NULL
);
782 if (xmlStrEqual(xdr_ns
->href
, XDR_href
))
784 else if (xdr_ns
->prefix
!= NULL
)
785 xmlNewNs(xsd_node
, xdr_ns
->href
, xdr_ns
->prefix
);
787 FIXME("unexpected default xmlns: %s\n", xdr_ns
->href
);
790 FOREACH_ATTR(xdr
, xdr_attr
)
792 xmlCopyProp(xsd_node
, xdr_attr
);
795 FOREACH_CHILD(xdr
, xdr_child
)
797 if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
798 XDR_E_AttributeType(xdr_child
, xsd_node
);
799 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
800 XDR_E_description(xdr_child
, xsd_node
);
801 else if (xmlStrEqual(xdr_child
->name
, xs_ElementType
))
802 XDR_E_ElementType(xdr_child
, xsd_node
);
804 FIXME("unexpected child <%s>\n", xdr_child
->name
);
810 xmlDocPtr
XDR_to_XSD_doc(xmlDocPtr xdr_doc
, xmlChar
const* nsURI
)
812 xmlDocPtr xsd_doc
= xmlNewDoc(NULL
);
814 TRACE("(%p)\n", xdr_doc
);
816 XDR_E_Schema(get_schema((xmlNodePtr
)xdr_doc
), (xmlNodePtr
)xsd_doc
, nsURI
);