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
26 # include <libxml/tree.h>
29 #include "wine/debug.h"
31 /* Both XDR and XSD are valid XML
32 * We just convert the doc tree, no need for a parser.
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
39 static const xmlChar DT_prefix
[] = "dt";
40 static const xmlChar DT_href
[] = "urn:schemas-microsoft-com:datatypes";
41 static const xmlChar XDR_href
[] = "urn:schemas-microsoft-com:xml-data";
42 static const xmlChar XSD_prefix
[] = "xsd";
43 static const xmlChar XSD_href
[] = "http://www.w3.org/2001/XMLSchema";
45 static const xmlChar xs_all
[] = "all";
46 static const xmlChar xs_annotation
[] = "annotation";
47 static const xmlChar xs_any
[] = "any";
48 static const xmlChar xs_anyAttribute
[] = "anyAttribute";
49 static const xmlChar xs_attribute
[] = "attribute";
50 static const xmlChar xs_AttributeType
[] = "AttributeType";
51 static const xmlChar xs_base
[] = "base";
52 static const xmlChar xs_choice
[] = "choice";
53 static const xmlChar xs_complexType
[] = "complexType";
54 static const xmlChar xs_content
[] = "content";
55 static const xmlChar xs_datatype
[] = "datatype";
56 static const xmlChar xs_default
[] = "default";
57 static const xmlChar xs_description
[] = "description";
58 static const xmlChar xs_documentation
[] = "documentation";
59 static const xmlChar xs_element
[] = "element";
60 static const xmlChar xs_ElementType
[] = "ElementType";
61 static const xmlChar xs_eltOnly
[] = "eltOnly";
62 static const xmlChar xs_enumeration
[] = "enumeration";
63 static const xmlChar xs_extension
[] = "extension";
64 static const xmlChar xs_group
[] = "group";
65 static const xmlChar xs_lax
[] = "lax";
66 static const xmlChar xs_length
[] = "length";
67 static const xmlChar xs_many
[] = "many";
68 static const xmlChar xs_maxOccurs
[] = "maxOccurs";
69 static const xmlChar xs_minOccurs
[] = "minOccurs";
70 static const xmlChar xs_mixed
[] = "mixed";
71 static const xmlChar xs_model
[] = "model";
72 static const xmlChar xs_name
[] = "name";
73 static const xmlChar xs_namespace
[] = "namespace";
74 static const xmlChar xs_no
[] = "no";
75 static const xmlChar xs_open
[] = "open";
76 static const xmlChar xs_optional
[] = "optional";
77 static const xmlChar xs_order
[] = "order";
78 static const xmlChar xs_processContents
[] = "processContents";
79 static const xmlChar xs_ref
[] = "ref";
80 static const xmlChar xs_required
[] = "required";
81 static const xmlChar xs_restriction
[] = "restriction";
82 static const xmlChar xs_schema
[] = "schema";
83 static const xmlChar xs_seq
[] = "seq";
84 static const xmlChar xs_sequence
[] = "sequence";
85 static const xmlChar xs_simpleContent
[] = "simpleContent";
86 static const xmlChar xs_simpleType
[] = "simpleType";
87 static const xmlChar xs_strict
[] = "strict";
88 static const xmlChar xs_targetNamespace
[] = "targetNamespace";
89 static const xmlChar xs_textOnly
[] = "textOnly";
90 static const xmlChar xs_true
[] = "true";
91 static const xmlChar xs_type
[] = "type";
92 static const xmlChar xs_unbounded
[] = "unbounded";
93 static const xmlChar xs_use
[] = "use";
94 static const xmlChar xs_value
[] = "value";
95 static const xmlChar xs_values
[] = "values";
96 static const xmlChar xs_xsd_string
[] = "xsd:string";
98 typedef enum _CONTENT_TYPE
106 typedef enum _ORDER_TYPE
113 #define FOREACH_CHILD(node, child) \
114 for (child = node->children; child != NULL; child = child->next) \
115 if (child->type == XML_ELEMENT_NODE)
117 #define FOREACH_ATTR(node, attr) \
118 for (attr = node->properties; attr != NULL; attr = attr->next)
120 #define FOREACH_NS(node, ns) \
121 for (ns = node->nsDef; ns != NULL; ns = ns->next)
123 static inline xmlNodePtr
get_schema(xmlNodePtr node
)
125 return xmlDocGetRootElement(node
->doc
);
128 static inline xmlNodePtr
get_child(xmlNodePtr node
, xmlChar
const* name
)
130 xmlNodePtr child
= NULL
;
133 FOREACH_CHILD(node
, child
)
135 if (xmlStrEqual(child
->name
, name
))
143 static inline xmlNodePtr
get_child_with_attr(xmlNodePtr node
, xmlChar
const* name
,
144 xmlChar
const* attr_ns
, xmlChar
const* attr_name
,
145 xmlChar
const* attr_val
)
150 FOREACH_CHILD(node
, node
)
152 if (xmlStrEqual(node
->name
, name
))
154 str
= (attr_ns
!= NULL
)? xmlGetNsProp(node
, attr_name
, attr_ns
) :
155 xmlGetProp(node
, attr_name
);
158 if (xmlStrEqual(str
, attr_val
))
172 static inline xmlNsPtr
get_dt_ns(xmlNodePtr node
)
176 node
= get_schema(node
);
177 assert(node
!= NULL
);
181 if (xmlStrEqual(ns
->href
, DT_href
))
188 static inline xmlChar
* get_dt_type(xmlNodePtr xdr
)
190 xmlChar
* str
= xmlGetNsProp(xdr
, xs_type
, DT_href
);
193 xmlNodePtr datatype
= get_child(xdr
, xs_datatype
);
195 str
= xmlGetNsProp(datatype
, xs_type
, DT_href
);
200 static inline xmlChar
* get_attr_val(xmlAttrPtr attr
)
202 return xmlNodeGetContent((xmlNodePtr
)attr
);
205 static inline xmlNodePtr
add_any_child(xmlNodePtr parent
, BOOL set_occurs
)
207 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_any
, NULL
);
210 xmlSetProp(child
, xs_minOccurs
, BAD_CAST
"0");
211 xmlSetProp(child
, xs_maxOccurs
, xs_unbounded
);
213 xmlSetProp(child
, xs_processContents
, xs_strict
);
217 static inline xmlNodePtr
add_anyAttribute_child(xmlNodePtr parent
)
219 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_anyAttribute
, NULL
);
220 xmlSetProp(child
, xs_processContents
, xs_lax
);
224 static inline xmlAttrPtr
copy_prop_ignore_ns(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
226 xmlChar
* str
= get_attr_val(xdr_attr
);
227 xmlAttrPtr attr
= xmlSetProp(node
, xdr_attr
->name
, str
);
231 static inline xmlAttrPtr
XDR_A_default(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
233 TRACE("(%p, %p)\n", xdr_attr
, node
);
235 return copy_prop_ignore_ns(xdr_attr
, node
);
238 static inline xmlAttrPtr
XDR_A_dt_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
240 xmlChar
* str
= get_attr_val(xdr_attr
);
243 TRACE("(%p, %p)\n", xdr_attr
, node
);
245 if (xmlStrEqual(str
, xs_enumeration
))
248 attr
= xmlSetNsProp(node
, get_dt_ns(node
), DT_prefix
, str
);
253 static xmlAttrPtr
XDR_A_maxOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
255 xmlChar
* str
= get_attr_val(xdr_attr
);
258 TRACE("(%p, %p)\n", xdr_attr
, node
);
260 if (xmlStrEqual(str
, BAD_CAST
"*"))
261 attr
= xmlSetProp(node
, xs_maxOccurs
, xs_unbounded
);
263 attr
= copy_prop_ignore_ns(xdr_attr
, node
);
269 static inline xmlAttrPtr
XDR_A_minOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
271 TRACE("(%p, %p)\n", xdr_attr
, node
);
273 return copy_prop_ignore_ns(xdr_attr
, node
);
276 static inline xmlAttrPtr
XDR_A_name(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
278 TRACE("(%p, %p)\n", xdr_attr
, node
);
280 return copy_prop_ignore_ns(xdr_attr
, node
);
283 static xmlAttrPtr
XDR_A_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
285 xmlChar
* str
= get_attr_val(xdr_attr
);
286 xmlAttrPtr attr
= xmlSetProp(node
, xs_ref
, str
);
288 TRACE("(%p, %p)\n", xdr_attr
, node
);
294 static xmlAttrPtr
XDR_A_required(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
296 xmlChar
* str
= get_attr_val(xdr_attr
);
299 TRACE("(%p, %p)\n", xdr_attr
, node
);
301 if (xmlStrEqual(str
, xs_no
))
302 attr
= xmlSetProp(node
, xs_use
, xs_optional
);
304 attr
= xmlSetProp(node
, xs_use
, xs_required
);
309 static xmlNodePtr
XDR_E_description(xmlNodePtr xdr
, xmlNodePtr parent
)
311 xmlNodePtr xsd_node
= xmlNewChild(parent
, NULL
, xs_annotation
, NULL
);
314 TRACE("(%p, %p)\n", xdr
, parent
);
316 xmlNewChild(xsd_node
, NULL
, xs_documentation
, xdr
->content
);
318 FOREACH_ATTR(xdr
, xdr_attr
)
320 xmlCopyProp(xsd_node
, xdr_attr
);
325 static xmlNodePtr
XDR_E_AttributeType(xmlNodePtr xdr
, xmlNodePtr parent
)
327 xmlChar
*str
, *type
= get_dt_type(xdr
);
328 xmlNodePtr xsd_node
, xsd_child
, xdr_child
;
331 TRACE("(%p, %p)\n", xdr
, parent
);
333 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
335 if (type
&& xmlStrEqual(type
, xs_enumeration
))
337 xmlChar
*tmp
, *tokBegin
, *tokEnd
= NULL
;
339 xsd_child
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
340 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_restriction
, NULL
);
341 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
343 tokBegin
= str
= xmlGetNsProp(xdr
, xs_values
, DT_href
);
344 while (tokBegin
&& *tokBegin
)
346 while (*tokBegin
&& isspace(*tokBegin
))
349 while (*tokEnd
&& !isspace(*tokEnd
))
351 if (tokEnd
== tokBegin
)
353 xsd_enum
= xmlNewChild(xsd_child
, NULL
, xs_enumeration
, NULL
);
354 tmp
= xmlStrndup(tokBegin
, tokEnd
-tokBegin
);
355 xmlSetProp(xsd_enum
, xs_value
, tmp
);
364 str
= xmlStrdup(DT_prefix
);
365 str
= xmlStrcat(str
, BAD_CAST
":");
366 str
= xmlStrcat(str
, type
);
367 xmlSetProp(xsd_node
, xs_type
, str
);
372 FOREACH_ATTR(xdr
, xdr_attr
)
374 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
375 XDR_A_default(xdr_attr
, xsd_node
);
376 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
377 XDR_A_name(xdr_attr
, xsd_node
);
378 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
379 XDR_A_dt_type(xdr_attr
, xsd_node
);
380 else if (xmlStrEqual(xdr_attr
->name
, xs_values
) && xdr_attr
->ns
== get_dt_ns(xdr
))
381 ; /* already handled */
382 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
383 XDR_A_required(xdr_attr
, xsd_node
);
385 xmlCopyProp(xsd_node
, xdr_attr
);
388 FOREACH_CHILD(xdr
, xdr_child
)
390 if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
391 ; /* already handled */
392 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
393 XDR_E_description(xdr_child
, xsd_node
);
395 FIXME("unexpected child <%s>\n", xdr_child
->name
);
401 static xmlNodePtr
XDR_E_attribute(xmlNodePtr xdr
, xmlNodePtr parent
)
403 xmlChar
* str
= xmlGetProp(xdr
, xs_type
);
404 xmlNodePtr xsd_node
, xdr_child
, xdr_attrType
;
407 TRACE("(%p, %p)\n", xdr
, parent
);
409 xdr_attrType
= get_child_with_attr(xdr
->parent
, xs_AttributeType
, NULL
, xs_name
, str
);
413 xsd_node
= XDR_E_AttributeType(xdr_attrType
, parent
);
415 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
417 FOREACH_ATTR(xdr
, xdr_attr
)
419 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
420 XDR_A_default(xdr_attr
, xsd_node
);
421 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && !xdr_attrType
)
422 XDR_A_type(xdr_attr
, xsd_node
);
423 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
424 XDR_A_required(xdr_attr
, xsd_node
);
426 xmlCopyProp(xsd_node
, xdr_attr
);
429 FOREACH_CHILD(xdr
, xdr_child
)
431 FIXME("unexpected child <%s>\n", xdr_child
->name
);
437 static xmlNodePtr
XDR_E_element(xmlNodePtr xdr
, xmlNodePtr parent
)
439 xmlNodePtr xdr_child
, xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
442 FOREACH_ATTR(xdr
, xdr_attr
)
444 if (xmlStrEqual(xdr_attr
->name
, xs_type
))
445 XDR_A_type(xdr_attr
, xsd_node
);
446 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
447 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
448 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
449 XDR_A_minOccurs(xdr_attr
, xsd_node
);
451 xmlCopyProp(xsd_node
, xdr_attr
);
454 FOREACH_CHILD(xdr
, xdr_child
)
456 FIXME("unexpected child <%s>\n", xdr_child
->name
);
462 static xmlNodePtr
XDR_E_group(xmlNodePtr xdr
, xmlNodePtr parent
)
464 xmlNodePtr xdr_child
, xsd_node
;
465 xmlChar
* str
= xmlGetProp(xdr
, xs_order
);
468 TRACE("(%p, %p)\n", xdr
, parent
);
470 if (!str
|| xmlStrEqual(str
, xs_seq
))
471 xsd_node
= xmlNewChild(parent
, NULL
, xs_sequence
, NULL
);
472 else if (xmlStrEqual(str
, xs_many
))
473 xsd_node
= xmlNewChild(parent
, NULL
, xs_choice
, NULL
);
475 xsd_node
= xmlNewChild(parent
, NULL
, xs_all
, NULL
);
478 FOREACH_ATTR(xdr
, xdr_attr
)
480 if (xmlStrEqual(xdr_attr
->name
, xs_order
))
481 ; /* already handled */
482 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
484 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
485 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
486 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
487 XDR_A_minOccurs(xdr_attr
, xsd_node
);
489 xmlCopyProp(xsd_node
, xdr_attr
);
492 FOREACH_CHILD(xdr
, xdr_child
)
494 if (xmlStrEqual(xdr_child
->name
, xs_description
))
495 XDR_E_description(xdr_child
, xsd_node
);
496 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
497 XDR_E_element(xdr_child
, xsd_node
);
503 static xmlNodePtr
XDR_E_ElementType(xmlNodePtr xdr
, xmlNodePtr parent
)
505 xmlChar
*str
, *type
= get_dt_type(xdr
);
507 int n_attributes
= 0, n_elements
= 0, n_groups
= 0;
508 CONTENT_TYPE content
;
510 xmlNodePtr xsd_node
, xsd_type
, xsd_child
, xdr_child
;
512 xmlNsPtr dt_ns
= get_dt_ns(parent
);
514 TRACE("(%p, %p)\n", xdr
, parent
);
516 str
= xmlGetProp(xdr
, xs_model
);
517 if (str
&& !xmlStrEqual(str
, xs_open
))
523 content
= CONTENT_TEXTONLY
;
527 str
= xmlGetProp(xdr
, xs_content
);
528 if (!str
|| xmlStrEqual(str
, xs_mixed
))
529 content
= CONTENT_MIXED
;
530 else if (xmlStrEqual(str
, xs_eltOnly
))
531 content
= CONTENT_ELTONLY
;
532 else if (xmlStrEqual(str
, xs_textOnly
))
533 content
= CONTENT_TEXTONLY
;
535 content
= CONTENT_EMPTY
;
539 str
= xmlGetProp(xdr
, xs_order
);
540 if (!str
|| xmlStrEqual(str
, xs_seq
))
544 else if (xmlStrEqual(str
, xs_many
))
555 FOREACH_CHILD(xdr
, xdr_child
)
557 if (xmlStrEqual(xdr_child
->name
, xs_element
))
559 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
561 else if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
565 xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
566 assert(xsd_node
!= NULL
);
570 case CONTENT_ELTONLY
:
573 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
575 if (content
== CONTENT_MIXED
)
576 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
579 xsd_base
= xmlNewChild(xsd_type
, NULL
, xs_sequence
, NULL
);
583 if (is_open
&& n_elements
< 2 && !n_groups
)
584 {/* no specific sequence of elements we need,
585 just has to start with the right one, if any */
586 if ((xdr_child
= get_child(xdr
, xs_element
)))
588 xsd_child
= XDR_E_element(xdr_child
, xsd_base
);
589 xmlUnsetProp(xsd_child
, xs_maxOccurs
);
597 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_sequence
, NULL
);
600 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_choice
, NULL
);
601 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
604 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_all
, NULL
);
608 FOREACH_CHILD(xdr
, xdr_child
)
610 if (xmlStrEqual(xdr_child
->name
, xs_element
))
611 XDR_E_element(xdr_child
, xsd_child
);
612 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
613 XDR_E_group(xdr_child
, xsd_child
);
619 FOREACH_CHILD(xdr
, xdr_child
)
621 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
622 XDR_E_attribute(xdr_child
, xsd_type
);
628 add_any_child(xsd_base
, TRUE
);
629 add_anyAttribute_child(xsd_type
);
633 case CONTENT_TEXTONLY
:
637 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
640 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
641 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
642 str
= xmlStrdup(DT_prefix
);
643 str
= xmlStrcat(str
, BAD_CAST
":");
644 str
= xmlStrcat(str
, type
);
645 xmlSetProp(xsd_child
, xs_base
, str
);
647 assert(dt_ns
!= NULL
);
648 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
652 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
653 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_choice
, NULL
);
654 xmlSetProp(xsd_child
, xs_minOccurs
, BAD_CAST
"0");
655 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
656 xsd_child
= add_any_child(xsd_child
, FALSE
);
657 xmlSetProp(xsd_child
, xs_namespace
, BAD_CAST
"##other");
658 xsd_child
= xsd_type
;
662 FOREACH_CHILD(xdr
, xdr_child
)
664 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
665 XDR_E_attribute(xdr_child
, xsd_child
);
668 xmlNewChild(xsd_child
, NULL
, xs_anyAttribute
, NULL
);
670 else if (!n_attributes
)
674 str
= xmlStrdup(DT_prefix
);
675 str
= xmlStrcat(str
, BAD_CAST
":");
676 str
= xmlStrcat(str
, type
);
677 xmlSetProp(xsd_node
, xs_type
, str
);
680 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
684 xmlSetProp(xsd_node
, xs_type
, xs_xsd_string
);
689 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
690 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
691 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
692 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
694 FOREACH_CHILD(xdr
, xdr_child
)
696 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
697 XDR_E_attribute(xdr_child
, xsd_child
);
702 case CONTENT_EMPTY
: /* not allowed with model="open" */
706 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
708 FOREACH_CHILD(xdr
, xdr_child
)
710 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
711 XDR_E_attribute(xdr_child
, xsd_type
);
716 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
717 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_restriction
, NULL
);
718 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
719 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_length
, NULL
);
720 xmlSetProp(xsd_child
, xs_value
, BAD_CAST
"0");
727 FOREACH_ATTR(xdr
, xdr_attr
)
729 if (xmlStrEqual(xdr_attr
->name
, xs_content
))
730 ; /* already handled */
731 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
732 XDR_A_name(xdr_attr
, xsd_node
);
733 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
734 XDR_A_dt_type(xdr_attr
, xsd_node
);
735 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
736 ; /* already handled */
737 else if (xmlStrEqual(xdr_attr
->name
, xs_order
))
738 ; /* already handled */
740 xmlCopyProp(xsd_node
, xdr_attr
);
744 FOREACH_CHILD(xdr
, xdr_child
)
746 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
747 ; /* already handled */
748 else if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
749 ; /* handled through XDR_E_attribute when parent is not <Schema> */
750 else if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
751 ; /* already handled */
752 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
753 XDR_E_description(xdr_child
, xsd_node
);
754 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
755 ; /* already handled */
756 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
757 ; /* already handled */
759 FIXME("unexpected child <%s>\n", xdr_child
->name
);
765 static xmlNodePtr
XDR_E_Schema(xmlNodePtr xdr
, xmlNodePtr parent
, xmlChar
const* nsURI
)
767 xmlNodePtr xsd_node
, xdr_child
;
771 TRACE("(%p, %p)\n", xdr
, parent
);
773 xsd_node
= xmlNewDocNode((xmlDocPtr
)parent
, NULL
, xs_schema
, NULL
);
774 xmlDocSetRootElement((xmlDocPtr
)parent
, xsd_node
);
775 assert(xsd_node
!= NULL
);
777 if (nsURI
&& *nsURI
) xmlNewNs(xsd_node
, nsURI
, NULL
);
778 ns
= xmlNewNs(xsd_node
, XSD_href
, XSD_prefix
);
781 xmlSetNs(xsd_node
, ns
);
783 if (nsURI
&& *nsURI
) xmlSetProp(xsd_node
, xs_targetNamespace
, nsURI
);
785 FOREACH_NS(xdr
, xdr_ns
)
787 /* TODO: special handling for dt namespace? */
788 assert(xdr_ns
->href
!= NULL
);
789 if (xmlStrEqual(xdr_ns
->href
, XDR_href
))
791 else if (xdr_ns
->prefix
!= NULL
)
792 xmlNewNs(xsd_node
, xdr_ns
->href
, xdr_ns
->prefix
);
794 FIXME("unexpected default xmlns: %s\n", xdr_ns
->href
);
797 FOREACH_ATTR(xdr
, xdr_attr
)
799 xmlCopyProp(xsd_node
, xdr_attr
);
802 FOREACH_CHILD(xdr
, xdr_child
)
804 if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
805 XDR_E_AttributeType(xdr_child
, xsd_node
);
806 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
807 XDR_E_description(xdr_child
, xsd_node
);
808 else if (xmlStrEqual(xdr_child
->name
, xs_ElementType
))
809 XDR_E_ElementType(xdr_child
, xsd_node
);
811 FIXME("unexpected child <%s>\n", xdr_child
->name
);
817 xmlDocPtr
XDR_to_XSD_doc(xmlDocPtr xdr_doc
, xmlChar
const* nsURI
)
819 xmlDocPtr xsd_doc
= xmlNewDoc(NULL
);
821 TRACE("(%p)\n", xdr_doc
);
823 XDR_E_Schema(get_schema((xmlNodePtr
)xdr_doc
), (xmlNodePtr
)xsd_doc
, nsURI
);
828 #endif /* HAVE_LIBXML2 */