Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
5fc439a7
Commit
5fc439a7
authored
Nov 12, 2010
by
Adam Martinson
Committed by
Alexandre Julliard
Nov 15, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msxml3: XDR schema support.
parent
2a4c07a7
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
916 additions
and
66 deletions
+916
-66
Makefile.in
dlls/msxml3/Makefile.in
+1
-0
schema.c
dlls/msxml3/schema.c
+52
-35
domdoc.c
dlls/msxml3/tests/domdoc.c
+6
-6
schema.c
dlls/msxml3/tests/schema.c
+25
-25
xdr.c
dlls/msxml3/xdr.c
+832
-0
No files found.
dlls/msxml3/Makefile.in
View file @
5fc439a7
...
...
@@ -30,6 +30,7 @@ C_SRCS = \
schema.c
\
text.c
\
uuid.c
\
xdr.c
\
xmldoc.c
\
xmlelem.c
...
...
dlls/msxml3/schema.c
View file @
5fc439a7
...
...
@@ -37,13 +37,13 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
msxml
);
/* We use a chained hashtable, which can hold any number of schemas
* TODO:
XDR schema support
* TODO:
versioned constructor
* TODO: grow/shrink hashtable depending on load factor
* TODO: implement read-only where appropriate
*/
/* This is just the number of buckets, should be prime */
#define DEFAULT_HASHTABLE_SIZE
31
#define DEFAULT_HASHTABLE_SIZE
17
#ifdef HAVE_LIBXML2
...
...
@@ -52,6 +52,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
#include <libxml/schemasInternals.h>
#include <libxml/hash.h>
xmlDocPtr
XDR_to_XSD_doc
(
xmlDocPtr
xdr_doc
,
xmlChar
const
*
nsURI
);
static
const
xmlChar
XSD_schema
[]
=
"schema"
;
static
const
xmlChar
XSD_nsURI
[]
=
"http://www.w3.org/2001/XMLSchema"
;
static
const
xmlChar
XDR_schema
[]
=
"Schema"
;
...
...
@@ -114,6 +116,9 @@ static LONG cache_entry_release(cache_entry* entry)
else
/* SCHEMA_TYPE_XDR */
{
xmldoc_release
(
entry
->
doc
);
xmldoc_release
(
entry
->
schema
->
doc
);
entry
->
schema
->
doc
=
NULL
;
xmlSchemaFree
(
entry
->
schema
);
heap_free
(
entry
);
}
}
...
...
@@ -147,7 +152,7 @@ static inline SCHEMA_TYPE schema_type_from_xmlDocPtr(xmlDocPtr schema)
return
SCHEMA_TYPE_INVALID
;
}
static
cache_entry
*
cache_entry_from_url
(
char
const
*
url
)
static
cache_entry
*
cache_entry_from_url
(
char
const
*
url
,
xmlChar
const
*
nsURI
)
{
cache_entry
*
entry
=
heap_alloc
(
sizeof
(
cache_entry
));
xmlSchemaParserCtxtPtr
spctx
=
xmlSchemaNewParserCtxt
(
url
);
...
...
@@ -157,6 +162,8 @@ static cache_entry* cache_entry_from_url(char const* url)
{
if
((
entry
->
schema
=
xmlSchemaParse
(
spctx
)))
{
/* TODO: if the nsURI is different from the default xmlns or targetNamespace,
* do we need to do something special here? */
xmldoc_init
(
entry
->
schema
->
doc
,
&
CLSID_DOMDocument40
);
entry
->
doc
=
entry
->
schema
->
doc
;
xmldoc_add_ref
(
entry
->
doc
);
...
...
@@ -177,12 +184,14 @@ static cache_entry* cache_entry_from_url(char const* url)
return
entry
;
}
static
cache_entry
*
cache_entry_from_xsd_doc
(
xmlDocPtr
doc
)
static
cache_entry
*
cache_entry_from_xsd_doc
(
xmlDocPtr
doc
,
xmlChar
const
*
nsURI
)
{
cache_entry
*
entry
=
heap_alloc
(
sizeof
(
cache_entry
));
xmlSchemaParserCtxtPtr
spctx
;
xmlDocPtr
new_doc
=
xmlCopyDoc
(
doc
,
1
);
/* TODO: if the nsURI is different from the default xmlns or targetNamespace,
* do we need to do something special here? */
entry
->
type
=
SCHEMA_TYPE_XSD
;
entry
->
ref
=
0
;
spctx
=
xmlSchemaNewDocParserCtxt
(
new_doc
);
...
...
@@ -204,18 +213,33 @@ static cache_entry* cache_entry_from_xsd_doc(xmlDocPtr doc)
return
entry
;
}
static
cache_entry
*
cache_entry_from_xdr_doc
(
xmlDocPtr
doc
)
static
cache_entry
*
cache_entry_from_xdr_doc
(
xmlDocPtr
doc
,
xmlChar
const
*
nsURI
)
{
cache_entry
*
entry
=
heap_alloc
(
sizeof
(
cache_entry
));
xmlDocPtr
new_doc
=
xmlCopyDoc
(
doc
,
1
);
xmlSchemaParserCtxtPtr
spctx
;
xmlDocPtr
new_doc
=
xmlCopyDoc
(
doc
,
1
),
xsd_doc
=
XDR_to_XSD_doc
(
doc
,
nsURI
);
FIXME
(
"XDR schema support not implemented
\n
"
);
entry
->
type
=
SCHEMA_TYPE_XDR
;
entry
->
ref
=
0
;
entry
->
schema
=
NULL
;
entry
->
doc
=
new_doc
;
xmldoc_init
(
entry
->
doc
,
&
CLSID_DOMDocument30
);
xmldoc_add_ref
(
entry
->
doc
);
spctx
=
xmlSchemaNewDocParserCtxt
(
xsd_doc
);
if
((
entry
->
schema
=
xmlSchemaParse
(
spctx
)))
{
entry
->
doc
=
new_doc
;
xmldoc_init
(
entry
->
schema
->
doc
,
&
CLSID_DOMDocument30
);
xmldoc_init
(
entry
->
doc
,
&
CLSID_DOMDocument30
);
xmldoc_add_ref
(
entry
->
doc
);
xmldoc_add_ref
(
entry
->
schema
->
doc
);
}
else
{
FIXME
(
"failed to parse doc
\n
"
);
xmlFreeDoc
(
new_doc
);
xmlFreeDoc
(
xsd_doc
);
heap_free
(
entry
);
entry
=
NULL
;
}
xmlSchemaFreeParserCtxt
(
spctx
);
return
entry
;
}
...
...
@@ -363,7 +387,7 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri
case
VT_BSTR
:
{
xmlChar
*
url
=
xmlChar_from_wchar
(
V_BSTR
(
&
var
));
cache_entry
*
entry
=
cache_entry_from_url
((
char
const
*
)
url
);
cache_entry
*
entry
=
cache_entry_from_url
((
char
const
*
)
url
,
name
);
heap_free
(
url
);
if
(
entry
)
...
...
@@ -402,11 +426,11 @@ static HRESULT WINAPI schema_cache_add(IXMLDOMSchemaCollection2* iface, BSTR uri
if
(
type
==
SCHEMA_TYPE_XSD
)
{
entry
=
cache_entry_from_xsd_doc
(
doc
);
entry
=
cache_entry_from_xsd_doc
(
doc
,
name
);
}
else
if
(
type
==
SCHEMA_TYPE_XDR
)
{
entry
=
cache_entry_from_xdr_doc
(
doc
);
entry
=
cache_entry_from_xdr_doc
(
doc
,
name
);
}
else
{
...
...
@@ -654,36 +678,29 @@ HRESULT SchemaCache_validate_tree(IXMLDOMSchemaCollection2* iface, xmlNodePtr tr
ns
=
tree
->
ns
->
href
;
}
entry
=
xmlHashLookup
(
This
->
cache
,
ns
);
entry
=
(
ns
!=
NULL
)
?
xmlHashLookup
(
This
->
cache
,
ns
)
:
xmlHashLookup
(
This
->
cache
,
BAD_CAST
""
);
/* TODO: if the ns is not in the cache, and it's a URL,
* do we try to load from that? */
if
(
entry
)
{
if
(
entry
->
type
==
SCHEMA_TYPE_XDR
)
{
FIXME
(
"partial stub: XDR schema support not implemented
\n
"
);
return
S_OK
;
}
else
if
(
entry
->
type
==
SCHEMA_TYPE_XSD
)
{
xmlSchemaValidCtxtPtr
svctx
;
int
err
;
/* TODO: if validateOnLoad property is false,
* we probably need to validate the schema here. */
svctx
=
xmlSchemaNewValidCtxt
(
entry
->
schema
);
xmlSchemaSetValidErrors
(
svctx
,
validate_error
,
validate_warning
,
NULL
);
xmlSchemaValidCtxtPtr
svctx
;
int
err
;
/* TODO: if validateOnLoad property is false,
* we probably need to validate the schema here. */
svctx
=
xmlSchemaNewValidCtxt
(
entry
->
schema
);
xmlSchemaSetValidErrors
(
svctx
,
validate_error
,
validate_warning
,
NULL
);
#ifdef HAVE_XMLSCHEMASSETVALIDSTRUCTUREDERRORS
xmlSchemaSetValidStructuredErrors
(
svctx
,
validate_serror
,
NULL
);
#endif
if
((
xmlNodePtr
)
tree
->
doc
==
tree
)
err
=
xmlSchemaValidateDoc
(
svctx
,
(
xmlDocPtr
)
tree
);
else
err
=
xmlSchemaValidateOneElement
(
svctx
,
tree
);
if
((
xmlNodePtr
)
tree
->
doc
==
tree
)
err
=
xmlSchemaValidateDoc
(
svctx
,
(
xmlDocPtr
)
tree
);
else
err
=
xmlSchemaValidateOneElement
(
svctx
,
tree
);
xmlSchemaFreeValidCtxt
(
svctx
);
return
err
?
S_FALSE
:
S_OK
;
}
xmlSchemaFreeValidCtxt
(
svctx
);
return
err
?
S_FALSE
:
S_OK
;
}
return
E_FAIL
;
...
...
dlls/msxml3/tests/domdoc.c
View file @
5fc439a7
...
...
@@ -7533,7 +7533,7 @@ static void test_XDR_schemas(void)
* this is fine */
err
=
NULL
;
bstr
=
NULL
;
todo_wine
ole_check
(
IXMLDOMDocument2_validate
(
doc
,
&
err
));
ole_check
(
IXMLDOMDocument2_validate
(
doc
,
&
err
));
ok
(
err
!=
NULL
,
"domdoc_validate() should always set err
\n
"
);
ole_expect
(
IXMLDOMParseError_get_reason
(
err
,
&
bstr
),
S_FALSE
);
ok
(
IXMLDOMParseError_get_reason
(
err
,
&
bstr
)
==
S_FALSE
,
"got error: %s
\n
"
,
wine_dbgstr_w
(
bstr
));
...
...
@@ -7559,7 +7559,7 @@ static void test_XDR_schemas(void)
* this is fine */
err
=
NULL
;
bstr
=
NULL
;
todo_wine
ole_check
(
IXMLDOMDocument2_validate
(
doc
,
&
err
));
ole_check
(
IXMLDOMDocument2_validate
(
doc
,
&
err
));
ok
(
err
!=
NULL
,
"domdoc_validate() should always set err
\n
"
);
ole_expect
(
IXMLDOMParseError_get_reason
(
err
,
&
bstr
),
S_FALSE
);
ok
(
IXMLDOMParseError_get_reason
(
err
,
&
bstr
)
==
S_FALSE
,
"got error: %s
\n
"
,
wine_dbgstr_w
(
bstr
));
...
...
@@ -7946,7 +7946,7 @@ static void test_get_dataType(void)
V_DISPATCH
(
&
v
)
=
NULL
;
ole_check
(
IXMLDOMDocument2_QueryInterface
(
schema
,
&
IID_IDispatch
,
(
void
**
)
&
V_DISPATCH
(
&
v
)));
ok
(
V_DISPATCH
(
&
v
)
!=
NULL
,
"failed to get IDispatch interface
\n
"
);
ole_check
(
IXMLDOMSchemaCollection_add
(
cache
,
_bstr_
(
"urn:x-schema:datatype-test-xdr"
),
v
));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache
,
_bstr_
(
"urn:x-schema:datatype-test-xdr"
),
v
));
VariantClear
(
&
v
);
/* associate the cache to the doc */
...
...
@@ -7961,11 +7961,11 @@ static void test_get_dataType(void)
err
=
NULL
;
l
=
0
;
bstr
=
NULL
;
ole_check
(
IXMLDOMDocument2_validate
(
doc
,
&
err
));
todo_wine
ole_check
(
IXMLDOMDocument2_validate
(
doc
,
&
err
));
ok
(
err
!=
NULL
,
"domdoc_validate() should always set err
\n
"
);
ole_expect
(
IXMLDOMParseError_get_errorCode
(
err
,
&
l
),
S_FALSE
);
todo_wine
ole_expect
(
IXMLDOMParseError_get_errorCode
(
err
,
&
l
),
S_FALSE
);
ole_expect
(
IXMLDOMParseError_get_reason
(
err
,
&
bstr
),
S_FALSE
);
ok
(
l
==
0
,
"got %08x : %s
\n
"
,
l
,
wine_dbgstr_w
(
bstr
));
todo_wine
ok
(
l
==
0
,
"got %08x : %s
\n
"
,
l
,
wine_dbgstr_w
(
bstr
));
if
(
bstr
)
SysFreeString
(
bstr
);
IXMLDOMParseError_Release
(
err
);
...
...
dlls/msxml3/tests/schema.c
View file @
5fc439a7
...
...
@@ -356,9 +356,9 @@ static void test_collection_refs(void)
ole_check
(
IXMLDOMDocument2_loadXML
(
schema3
,
_bstr_
(
xdr_schema3_xml
),
&
b
));
ok
(
b
==
VARIANT_TRUE
,
"failed to load XML
\n
"
);
ole_check
(
IXMLDOMSchemaCollection_add
(
cache1
,
_bstr_
(
xdr_schema1_uri
),
_variantdoc_
(
schema1
)));
ole_check
(
IXMLDOMSchemaCollection_add
(
cache2
,
_bstr_
(
xdr_schema2_uri
),
_variantdoc_
(
schema2
)));
ole_check
(
IXMLDOMSchemaCollection_add
(
cache3
,
_bstr_
(
xdr_schema3_uri
),
_variantdoc_
(
schema3
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache1
,
_bstr_
(
xdr_schema1_uri
),
_variantdoc_
(
schema1
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache2
,
_bstr_
(
xdr_schema2_uri
),
_variantdoc_
(
schema2
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache3
,
_bstr_
(
xdr_schema3_uri
),
_variantdoc_
(
schema3
)));
check_ref_expr
(
IXMLDOMDocument2_Release
(
schema1
),
0
);
check_ref_expr
(
IXMLDOMDocument2_Release
(
schema2
),
0
);
...
...
@@ -383,15 +383,15 @@ static void test_collection_refs(void)
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache1
,
&
length
));
ok
(
length
==
1
,
"expected length 1, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
1
,
"expected length 1, got %i
\n
"
,
length
);
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache2
,
&
length
));
ok
(
length
==
2
,
"expected length 2, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
2
,
"expected length 2, got %i
\n
"
,
length
);
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache3
,
&
length
));
ok
(
length
==
3
,
"expected length 3, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
3
,
"expected length 3, got %i
\n
"
,
length
);
/* merging collections does not affect the ref count */
...
...
@@ -484,23 +484,23 @@ static void test_length(void)
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache
,
&
length
));
ok
(
length
==
0
,
"expected length 0, got %i
\n
"
,
length
);
ole_check
(
IXMLDOMSchemaCollection_add
(
cache
,
_bstr_
(
xdr_schema1_uri
),
_variantdoc_
(
schema1
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache
,
_bstr_
(
xdr_schema1_uri
),
_variantdoc_
(
schema1
)));
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache
,
&
length
));
ok
(
length
==
1
,
"expected length 1, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
1
,
"expected length 1, got %i
\n
"
,
length
);
ole_check
(
IXMLDOMSchemaCollection_add
(
cache
,
_bstr_
(
xdr_schema2_uri
),
_variantdoc_
(
schema2
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache
,
_bstr_
(
xdr_schema2_uri
),
_variantdoc_
(
schema2
)));
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache
,
&
length
));
ok
(
length
==
2
,
"expected length 2, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
2
,
"expected length 2, got %i
\n
"
,
length
);
ole_check
(
IXMLDOMSchemaCollection_add
(
cache
,
_bstr_
(
xdr_schema3_uri
),
_variantdoc_
(
schema3
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache
,
_bstr_
(
xdr_schema3_uri
),
_variantdoc_
(
schema3
)));
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache
,
&
length
));
ok
(
length
==
3
,
"expected length 3, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
3
,
"expected length 3, got %i
\n
"
,
length
);
/* adding with VT_NULL is the same as removing */
V_VT
(
&
v
)
=
VT_NULL
;
...
...
@@ -508,13 +508,13 @@ static void test_length(void)
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache
,
&
length
));
ok
(
length
==
2
,
"expected length 2, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
2
,
"expected length 2, got %i
\n
"
,
length
);
ole_check
(
IXMLDOMSchemaCollection_remove
(
cache
,
_bstr_
(
xdr_schema2_uri
)));
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache
,
&
length
));
ok
(
length
==
1
,
"expected length 1, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
1
,
"expected length 1, got %i
\n
"
,
length
);
ole_check
(
IXMLDOMSchemaCollection_remove
(
cache
,
_bstr_
(
xdr_schema3_uri
)));
...
...
@@ -567,13 +567,13 @@ static void test_collection_content(void)
ole_check
(
IXMLDOMDocument2_loadXML
(
schema3
,
_bstr_
(
xdr_schema3_xml
),
&
b
));
ok
(
b
==
VARIANT_TRUE
,
"failed to load XML
\n
"
);
ole_check
(
IXMLDOMSchemaCollection_add
(
cache1
,
_bstr_
(
xdr_schema1_uri
),
_variantdoc_
(
schema1
)));
ole_check
(
IXMLDOMSchemaCollection_add
(
cache1
,
_bstr_
(
xdr_schema2_uri
),
_variantdoc_
(
schema2
)));
ole_check
(
IXMLDOMSchemaCollection_add
(
cache1
,
_bstr_
(
xdr_schema3_uri
),
_variantdoc_
(
schema3
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache1
,
_bstr_
(
xdr_schema1_uri
),
_variantdoc_
(
schema1
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache1
,
_bstr_
(
xdr_schema2_uri
),
_variantdoc_
(
schema2
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache1
,
_bstr_
(
xdr_schema3_uri
),
_variantdoc_
(
schema3
)));
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache1
,
&
length
));
ok
(
length
==
3
,
"expected length 3, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
3
,
"expected length 3, got %i
\n
"
,
length
);
IXMLDOMDocument2_Release
(
schema1
);
IXMLDOMDocument2_Release
(
schema2
);
...
...
@@ -598,15 +598,15 @@ static void test_collection_content(void)
ok
(
b
==
VARIANT_TRUE
,
"failed to load XML
\n
"
);
/* combining XDR and XSD schemas in the same cache is fine */
ole_check
(
IXMLDOMSchemaCollection_add
(
cache2
,
_bstr_
(
xdr_schema1_uri
),
_variantdoc_
(
schema1
)));
ole_check
(
IXMLDOMSchemaCollection_add
(
cache2
,
_bstr_
(
xdr_schema2_uri
),
_variantdoc_
(
schema2
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache2
,
_bstr_
(
xdr_schema1_uri
),
_variantdoc_
(
schema1
)));
todo_wine
ole_check
(
IXMLDOMSchemaCollection_add
(
cache2
,
_bstr_
(
xdr_schema2_uri
),
_variantdoc_
(
schema2
)));
ole_check
(
IXMLDOMSchemaCollection_add
(
cache2
,
_bstr_
(
xsd_schema1_uri
),
_variantdoc_
(
schema3
)));
ole_check
(
IXMLDOMSchemaCollection_add
(
cache2
,
_bstr_
(
xsd_schema2_uri
),
_variantdoc_
(
schema4
)));
ole_check
(
IXMLDOMSchemaCollection_add
(
cache2
,
_bstr_
(
xsd_schema3_uri
),
_variantdoc_
(
schema5
)));
length
=
-
1
;
ole_check
(
IXMLDOMSchemaCollection_get_length
(
cache2
,
&
length
));
ok
(
length
==
5
,
"expected length 5, got %i
\n
"
,
length
);
todo_wine
ok
(
length
==
5
,
"expected length 5, got %i
\n
"
,
length
);
IXMLDOMDocument2_Release
(
schema1
);
IXMLDOMDocument2_Release
(
schema2
);
...
...
@@ -637,12 +637,12 @@ static void test_collection_content(void)
for
(
i
=
0
;
i
<
3
;
++
i
)
{
bstr
=
NULL
;
ole_check
(
IXMLDOMSchemaCollection_get_namespaceURI
(
cache1
,
i
,
&
bstr
));
ok
(
bstr
!=
NULL
&&
*
bstr
,
"expected non-empty string
\n
"
);
todo_wine
ole_check
(
IXMLDOMSchemaCollection_get_namespaceURI
(
cache1
,
i
,
&
bstr
));
todo_wine
ok
(
bstr
!=
NULL
&&
*
bstr
,
"expected non-empty string
\n
"
);
content
[
i
]
=
bstr
;
for
(
j
=
0
;
j
<
i
;
++
j
)
ok
(
lstrcmpW
(
content
[
j
],
bstr
),
"got duplicate entry
\n
"
);
todo_wine
ok
(
lstrcmpW
(
content
[
j
],
bstr
),
"got duplicate entry
\n
"
);
}
for
(
i
=
0
;
i
<
3
;
++
i
)
...
...
@@ -651,7 +651,7 @@ static void test_collection_content(void)
content
[
i
]
=
NULL
;
}
if
(
cache2
)
if
(
FALSE
&&
cache2
)
{
for
(
i
=
0
;
i
<
5
;
++
i
)
{
...
...
dlls/msxml3/xdr.c
0 → 100644
View file @
5fc439a7
/*
* XDR (XML-Data Reduced) -> XSD (XML Schema Document) conversion
*
* Copyright 2010 Adam Martinson for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/debug.h"
#include <assert.h>
WINE_DEFAULT_DEBUG_CHANNEL
(
msxml
);
/* Both XDR and XSD are valid XML
* We just convert the doc tree, no need for a parser.
*/
#ifdef HAVE_LIBXML2
#include <libxml/tree.h>
static
const
xmlChar
DT_prefix
[]
=
"dt"
;
static
const
xmlChar
DT_href
[]
=
"urn:schemas-microsoft-com:datatypes"
;
static
const
xmlChar
XDR_prefix
[]
=
"xdr"
;
static
const
xmlChar
XDR_href
[]
=
"urn:schemas-microsoft-com:xml-data"
;
static
const
xmlChar
XSD_prefix
[]
=
"xsd"
;
static
const
xmlChar
XSD_href
[]
=
"http://www.w3.org/2001/XMLSchema"
;
static
const
xmlChar
xs_all
[]
=
"all"
;
static
const
xmlChar
xs_annotation
[]
=
"annotation"
;
static
const
xmlChar
xs_any
[]
=
"any"
;
static
const
xmlChar
xs_anyAttribute
[]
=
"anyAttribute"
;
static
const
xmlChar
xs_attribute
[]
=
"attribute"
;
static
const
xmlChar
xs_AttributeType
[]
=
"AttributeType"
;
static
const
xmlChar
xs_base
[]
=
"base"
;
static
const
xmlChar
xs_choice
[]
=
"choice"
;
static
const
xmlChar
xs_complexContent
[]
=
"complexContent"
;
static
const
xmlChar
xs_complexType
[]
=
"complexType"
;
static
const
xmlChar
xs_content
[]
=
"content"
;
static
const
xmlChar
xs_datatype
[]
=
"datatype"
;
static
const
xmlChar
xs_default
[]
=
"default"
;
static
const
xmlChar
xs_description
[]
=
"description"
;
static
const
xmlChar
xs_documentation
[]
=
"documentation"
;
static
const
xmlChar
xs_element
[]
=
"element"
;
static
const
xmlChar
xs_ElementType
[]
=
"ElementType"
;
static
const
xmlChar
xs_eltOnly
[]
=
"eltOnly"
;
static
const
xmlChar
xs_empty
[]
=
"empty"
;
static
const
xmlChar
xs_enumeration
[]
=
"enumeration"
;
static
const
xmlChar
xs_extension
[]
=
"extension"
;
static
const
xmlChar
xs_group
[]
=
"group"
;
static
const
xmlChar
xs_lax
[]
=
"lax"
;
static
const
xmlChar
xs_length
[]
=
"length"
;
static
const
xmlChar
xs_many
[]
=
"many"
;
static
const
xmlChar
xs_maxOccurs
[]
=
"maxOccurs"
;
static
const
xmlChar
xs_minOccurs
[]
=
"minOccurs"
;
static
const
xmlChar
xs_mixed
[]
=
"mixed"
;
static
const
xmlChar
xs_model
[]
=
"model"
;
static
const
xmlChar
xs_name
[]
=
"name"
;
static
const
xmlChar
xs_namespace
[]
=
"namespace"
;
static
const
xmlChar
xs_no
[]
=
"no"
;
static
const
xmlChar
xs_one
[]
=
"one"
;
static
const
xmlChar
xs_open
[]
=
"open"
;
static
const
xmlChar
xs_optional
[]
=
"optional"
;
static
const
xmlChar
xs_order
[]
=
"order"
;
static
const
xmlChar
xs_processContents
[]
=
"processContents"
;
static
const
xmlChar
xs_ref
[]
=
"ref"
;
static
const
xmlChar
xs_required
[]
=
"required"
;
static
const
xmlChar
xs_restriction
[]
=
"restriction"
;
static
const
xmlChar
xs_schema
[]
=
"schema"
;
static
const
xmlChar
xs_Schema
[]
=
"Schema"
;
static
const
xmlChar
xs_seq
[]
=
"seq"
;
static
const
xmlChar
xs_sequence
[]
=
"sequence"
;
static
const
xmlChar
xs_simpleContent
[]
=
"simpleContent"
;
static
const
xmlChar
xs_simpleType
[]
=
"simpleType"
;
static
const
xmlChar
xs_strict
[]
=
"strict"
;
static
const
xmlChar
xs_targetNamespace
[]
=
"targetNamespace"
;
static
const
xmlChar
xs_textOnly
[]
=
"textOnly"
;
static
const
xmlChar
xs_true
[]
=
"true"
;
static
const
xmlChar
xs_type
[]
=
"type"
;
static
const
xmlChar
xs_unbounded
[]
=
"unbounded"
;
static
const
xmlChar
xs_use
[]
=
"use"
;
static
const
xmlChar
xs_value
[]
=
"value"
;
static
const
xmlChar
xs_values
[]
=
"values"
;
static
const
xmlChar
xs_xsd_string
[]
=
"xsd:string"
;
static
const
xmlChar
xs_yes
[]
=
"yes"
;
typedef
enum
_CONTENT_TYPE
{
CONTENT_EMPTY
,
CONTENT_TEXTONLY
,
CONTENT_ELTONLY
,
CONTENT_MIXED
}
CONTENT_TYPE
;
typedef
enum
_ORDER_TYPE
{
ORDER_SEQ
,
ORDER_MANY
,
ORDER_ONE
}
ORDER_TYPE
;
#define FOREACH_CHILD(node, child) \
for (child = node->children; child != NULL; child = child->next) \
if (child->type == XML_ELEMENT_NODE)
#define FOREACH_ATTR(node, attr) \
for (attr = node->properties; attr != NULL; attr = attr->next)
#define FOREACH_NS(node, ns) \
for (ns = node->nsDef; ns != NULL; ns = ns->next)
static
inline
xmlNodePtr
get_schema
(
xmlNodePtr
node
)
{
return
xmlDocGetRootElement
(
node
->
doc
);
}
static
inline
const
xmlNodePtr
get_child
(
xmlNodePtr
node
,
xmlChar
const
*
name
)
{
xmlNodePtr
child
=
NULL
;
if
(
node
)
{
FOREACH_CHILD
(
node
,
child
)
{
if
(
xmlStrEqual
(
child
->
name
,
name
))
break
;
}
}
return
child
;
}
static
inline
const
xmlNodePtr
get_child_with_attr
(
xmlNodePtr
node
,
xmlChar
const
*
name
,
xmlChar
const
*
attr_ns
,
xmlChar
const
*
attr_name
,
xmlChar
const
*
attr_val
)
{
xmlChar
*
str
;
if
(
node
)
{
FOREACH_CHILD
(
node
,
node
)
{
if
(
xmlStrEqual
(
node
->
name
,
name
))
{
str
=
(
attr_ns
!=
NULL
)
?
xmlGetNsProp
(
node
,
attr_name
,
attr_ns
)
:
xmlGetProp
(
node
,
attr_name
);
if
(
str
)
{
if
(
xmlStrEqual
(
str
,
attr_val
))
{
xmlFree
(
str
);
return
node
;
}
xmlFree
(
str
);
}
}
}
}
return
NULL
;
}
static
inline
xmlNsPtr
get_dt_ns
(
xmlNodePtr
node
)
{
xmlNsPtr
ns
;
node
=
get_schema
(
node
);
assert
(
node
!=
NULL
);
FOREACH_NS
(
node
,
ns
)
{
if
(
xmlStrEqual
(
ns
->
href
,
DT_href
))
break
;
}
return
ns
;
}
static
inline
xmlChar
*
get_dt_type
(
xmlNodePtr
xdr
)
{
xmlChar
*
str
=
xmlGetNsProp
(
xdr
,
xs_type
,
DT_href
);
if
(
!
str
)
{
xmlNodePtr
datatype
=
get_child
(
xdr
,
xs_datatype
);
if
(
datatype
)
str
=
xmlGetNsProp
(
datatype
,
xs_type
,
DT_href
);
}
return
str
;
}
static
inline
xmlChar
*
get_attr_val
(
xmlAttrPtr
attr
)
{
return
xmlNodeGetContent
((
xmlNodePtr
)
attr
);
}
static
inline
xmlNodePtr
add_any_child
(
xmlNodePtr
parent
,
BOOL
set_occurs
)
{
xmlNodePtr
child
=
xmlNewChild
(
parent
,
NULL
,
xs_any
,
NULL
);
if
(
set_occurs
)
{
xmlSetProp
(
child
,
xs_minOccurs
,
BAD_CAST
"0"
);
xmlSetProp
(
child
,
xs_maxOccurs
,
xs_unbounded
);
}
xmlSetProp
(
child
,
xs_processContents
,
xs_strict
);
return
child
;
}
static
inline
xmlNodePtr
add_anyAttribute_child
(
xmlNodePtr
parent
)
{
xmlNodePtr
child
=
xmlNewChild
(
parent
,
NULL
,
xs_anyAttribute
,
NULL
);
xmlSetProp
(
child
,
xs_processContents
,
xs_lax
);
return
child
;
}
static
inline
xmlAttrPtr
copy_prop_ignore_ns
(
xmlAttrPtr
xdr_attr
,
xmlNodePtr
node
)
{
xmlChar
*
str
=
get_attr_val
(
xdr_attr
);
xmlAttrPtr
attr
=
xmlSetProp
(
node
,
xdr_attr
->
name
,
str
);
xmlFree
(
str
);
return
attr
;
}
static
inline
xmlAttrPtr
XDR_A_default
(
xmlAttrPtr
xdr_attr
,
xmlNodePtr
node
)
{
TRACE
(
"(%p, %p)
\n
"
,
xdr_attr
,
node
);
return
copy_prop_ignore_ns
(
xdr_attr
,
node
);
}
static
inline
xmlAttrPtr
XDR_A_dt_type
(
xmlAttrPtr
xdr_attr
,
xmlNodePtr
node
)
{
xmlChar
*
str
=
get_attr_val
(
xdr_attr
);
xmlAttrPtr
attr
;
TRACE
(
"(%p, %p)
\n
"
,
xdr_attr
,
node
);
if
(
xmlStrEqual
(
str
,
xs_enumeration
))
attr
=
NULL
;
else
attr
=
xmlSetNsProp
(
node
,
get_dt_ns
(
node
),
DT_prefix
,
str
);
xmlFree
(
str
);
return
attr
;
}
static
xmlAttrPtr
XDR_A_maxOccurs
(
xmlAttrPtr
xdr_attr
,
xmlNodePtr
node
)
{
xmlChar
*
str
=
get_attr_val
(
xdr_attr
);
xmlAttrPtr
attr
;
TRACE
(
"(%p, %p)
\n
"
,
xdr_attr
,
node
);
if
(
xmlStrEqual
(
str
,
BAD_CAST
"*"
))
attr
=
xmlSetProp
(
node
,
xs_maxOccurs
,
xs_unbounded
);
else
attr
=
copy_prop_ignore_ns
(
xdr_attr
,
node
);
xmlFree
(
str
);
return
attr
;
}
static
inline
xmlAttrPtr
XDR_A_minOccurs
(
xmlAttrPtr
xdr_attr
,
xmlNodePtr
node
)
{
TRACE
(
"(%p, %p)
\n
"
,
xdr_attr
,
node
);
return
copy_prop_ignore_ns
(
xdr_attr
,
node
);
}
static
inline
xmlAttrPtr
XDR_A_name
(
xmlAttrPtr
xdr_attr
,
xmlNodePtr
node
)
{
TRACE
(
"(%p, %p)
\n
"
,
xdr_attr
,
node
);
return
copy_prop_ignore_ns
(
xdr_attr
,
node
);
}
static
xmlAttrPtr
XDR_A_type
(
xmlAttrPtr
xdr_attr
,
xmlNodePtr
node
)
{
xmlChar
*
str
=
get_attr_val
(
xdr_attr
);
xmlAttrPtr
attr
=
xmlSetProp
(
node
,
xs_ref
,
str
);
TRACE
(
"(%p, %p)
\n
"
,
xdr_attr
,
node
);
xmlFree
(
str
);
return
attr
;
}
static
xmlAttrPtr
XDR_A_required
(
xmlAttrPtr
xdr_attr
,
xmlNodePtr
node
)
{
xmlChar
*
str
=
get_attr_val
(
xdr_attr
);
xmlAttrPtr
attr
;
TRACE
(
"(%p, %p)
\n
"
,
xdr_attr
,
node
);
if
(
xmlStrEqual
(
str
,
xs_no
))
attr
=
xmlSetProp
(
node
,
xs_use
,
xs_optional
);
else
/* yes */
attr
=
xmlSetProp
(
node
,
xs_use
,
xs_required
);
xmlFree
(
str
);
return
attr
;
}
static
xmlNodePtr
XDR_E_description
(
xmlNodePtr
xdr
,
xmlNodePtr
parent
)
{
xmlNodePtr
xsd_node
=
xmlNewChild
(
parent
,
NULL
,
xs_annotation
,
NULL
);
xmlAttrPtr
xdr_attr
;
TRACE
(
"(%p, %p)
\n
"
,
xdr
,
parent
);
xmlNewChild
(
xsd_node
,
NULL
,
xs_documentation
,
xdr
->
content
);
FOREACH_ATTR
(
xdr
,
xdr_attr
)
{
xmlCopyProp
(
xsd_node
,
xdr_attr
);
}
return
xsd_node
;
}
static
xmlNodePtr
XDR_E_AttributeType
(
xmlNodePtr
xdr
,
xmlNodePtr
parent
)
{
xmlChar
*
str
,
*
type
=
get_dt_type
(
xdr
);
xmlNodePtr
xsd_node
,
xsd_child
,
xdr_child
;
xmlAttrPtr
xdr_attr
;
TRACE
(
"(%p, %p)
\n
"
,
xdr
,
parent
);
xsd_node
=
xmlNewChild
(
parent
,
NULL
,
xs_attribute
,
NULL
);
if
(
type
&&
xmlStrEqual
(
type
,
xs_enumeration
))
{
xmlChar
*
tmp
,
*
tokBegin
,
*
tokEnd
=
NULL
;
xmlNodePtr
xsd_enum
;
xsd_child
=
xmlNewChild
(
xsd_node
,
NULL
,
xs_simpleType
,
NULL
);
xsd_child
=
xmlNewChild
(
xsd_child
,
NULL
,
xs_restriction
,
NULL
);
xmlSetProp
(
xsd_child
,
xs_base
,
xs_xsd_string
);
tokBegin
=
str
=
xmlGetNsProp
(
xdr
,
xs_values
,
DT_href
);
while
(
tokBegin
&&
*
tokBegin
)
{
while
(
*
tokBegin
&&
isspace
(
*
tokBegin
))
++
tokBegin
;
tokEnd
=
tokBegin
;
while
(
*
tokEnd
&&
!
isspace
(
*
tokEnd
))
++
tokEnd
;
if
(
tokEnd
==
tokBegin
)
break
;
xsd_enum
=
xmlNewChild
(
xsd_child
,
NULL
,
xs_enumeration
,
NULL
);
tmp
=
xmlStrndup
(
tokBegin
,
tokEnd
-
tokBegin
);
xmlSetProp
(
xsd_enum
,
xs_value
,
tmp
);
xmlFree
(
tmp
);
tokBegin
=
tokEnd
;
}
xmlFree
(
str
);
}
else
if
(
type
)
{
str
=
xmlStrdup
(
DT_prefix
);
str
=
xmlStrcat
(
str
,
BAD_CAST
":"
);
str
=
xmlStrcat
(
str
,
type
);
xmlSetProp
(
xsd_node
,
xs_type
,
str
);
xmlFree
(
str
);
}
xmlFree
(
type
);
FOREACH_ATTR
(
xdr
,
xdr_attr
)
{
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_default
))
XDR_A_default
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_name
))
XDR_A_name
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_type
)
&&
xdr_attr
->
ns
==
get_dt_ns
(
xdr
))
XDR_A_dt_type
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_values
)
&&
xdr_attr
->
ns
==
get_dt_ns
(
xdr
))
;
/* already handled */
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_required
))
XDR_A_required
(
xdr_attr
,
xsd_node
);
else
xmlCopyProp
(
xsd_node
,
xdr_attr
);
}
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_datatype
))
;
/* already handled */
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_description
))
XDR_E_description
(
xdr_child
,
xsd_node
);
else
FIXME
(
"unexpected child <%s>
\n
"
,
xdr_child
->
name
);
}
return
xsd_node
;
}
static
xmlNodePtr
XDR_E_attribute
(
xmlNodePtr
xdr
,
xmlNodePtr
parent
)
{
xmlChar
*
str
=
xmlGetProp
(
xdr
,
xs_type
);
xmlNodePtr
xsd_node
,
xdr_child
,
xdr_attrType
;
xmlAttrPtr
xdr_attr
;
TRACE
(
"(%p, %p)
\n
"
,
xdr
,
parent
);
xdr_attrType
=
get_child_with_attr
(
xdr
->
parent
,
xs_AttributeType
,
NULL
,
xs_name
,
str
);
xmlFree
(
str
);
if
(
xdr_attrType
)
xsd_node
=
XDR_E_AttributeType
(
xdr_attrType
,
parent
);
else
xsd_node
=
xmlNewChild
(
parent
,
NULL
,
xs_attribute
,
NULL
);
FOREACH_ATTR
(
xdr
,
xdr_attr
)
{
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_default
))
XDR_A_default
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_type
)
&&
!
xdr_attrType
)
XDR_A_type
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_required
))
XDR_A_required
(
xdr_attr
,
xsd_node
);
else
xmlCopyProp
(
xsd_node
,
xdr_attr
);
}
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
FIXME
(
"unexpected child <%s>
\n
"
,
xdr_child
->
name
);
}
return
xsd_node
;
}
static
xmlNodePtr
XDR_E_element
(
xmlNodePtr
xdr
,
xmlNodePtr
parent
)
{
xmlNodePtr
xdr_child
,
xsd_node
=
xmlNewChild
(
parent
,
NULL
,
xs_element
,
NULL
);
xmlAttrPtr
xdr_attr
;
FOREACH_ATTR
(
xdr
,
xdr_attr
)
{
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_type
))
XDR_A_type
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_maxOccurs
))
XDR_A_maxOccurs
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_minOccurs
))
XDR_A_minOccurs
(
xdr_attr
,
xsd_node
);
else
xmlCopyProp
(
xsd_node
,
xdr_attr
);
}
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
FIXME
(
"unexpected child <%s>
\n
"
,
xdr_child
->
name
);
}
return
xsd_node
;
}
static
xmlNodePtr
XDR_E_group
(
xmlNodePtr
xdr
,
xmlNodePtr
parent
)
{
xmlNodePtr
xdr_child
,
xsd_node
;
xmlChar
*
str
=
xmlGetProp
(
xdr
,
xs_order
);
xmlAttrPtr
xdr_attr
;
TRACE
(
"(%p, %p)
\n
"
,
xdr
,
parent
);
if
(
!
str
||
xmlStrEqual
(
str
,
xs_seq
))
xsd_node
=
xmlNewChild
(
parent
,
NULL
,
xs_sequence
,
NULL
);
else
if
(
xmlStrEqual
(
str
,
xs_many
))
xsd_node
=
xmlNewChild
(
parent
,
NULL
,
xs_choice
,
NULL
);
else
/* one */
xsd_node
=
xmlNewChild
(
parent
,
NULL
,
xs_all
,
NULL
);
xmlFree
(
str
);
FOREACH_ATTR
(
xdr
,
xdr_attr
)
{
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_order
))
;
/* already handled */
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_model
))
;
/* ignored */
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_maxOccurs
))
XDR_A_maxOccurs
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_minOccurs
))
XDR_A_minOccurs
(
xdr_attr
,
xsd_node
);
else
xmlCopyProp
(
xsd_node
,
xdr_attr
);
}
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_description
))
XDR_E_description
(
xdr_child
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_element
))
XDR_E_element
(
xdr_child
,
xsd_node
);
}
return
xsd_node
;
}
static
xmlNodePtr
XDR_E_ElementType
(
xmlNodePtr
xdr
,
xmlNodePtr
parent
)
{
xmlChar
*
str
,
*
type
=
get_dt_type
(
xdr
);
BOOL
is_open
=
TRUE
;
int
n_attributes
=
0
,
n_elements
=
0
,
n_groups
=
0
;
CONTENT_TYPE
content
;
ORDER_TYPE
order
;
xmlNodePtr
xsd_node
,
xsd_type
,
xsd_child
,
xdr_child
;
xmlAttrPtr
xdr_attr
;
xmlNsPtr
dt_ns
=
get_dt_ns
(
parent
);
TRACE
(
"(%p, %p)
\n
"
,
xdr
,
parent
);
str
=
xmlGetProp
(
xdr
,
xs_model
);
if
(
str
&&
!
xmlStrEqual
(
str
,
xs_open
))
is_open
=
FALSE
;
xmlFree
(
str
);
if
(
type
)
{
content
=
CONTENT_TEXTONLY
;
}
else
{
str
=
xmlGetProp
(
xdr
,
xs_content
);
if
(
!
str
||
xmlStrEqual
(
str
,
xs_mixed
))
content
=
CONTENT_MIXED
;
else
if
(
xmlStrEqual
(
str
,
xs_eltOnly
))
content
=
CONTENT_ELTONLY
;
else
if
(
xmlStrEqual
(
str
,
xs_textOnly
))
content
=
CONTENT_TEXTONLY
;
else
/* empty */
content
=
CONTENT_EMPTY
;
xmlFree
(
str
);
}
str
=
xmlGetProp
(
xdr
,
xs_order
);
if
(
!
str
||
xmlStrEqual
(
str
,
xs_seq
))
{
order
=
ORDER_SEQ
;
}
else
if
(
xmlStrEqual
(
str
,
xs_many
))
{
order
=
ORDER_MANY
;
}
else
/* one */
{
order
=
ORDER_ONE
;
is_open
=
FALSE
;
}
xmlFree
(
str
);
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_element
))
++
n_elements
;
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_group
))
++
n_groups
;
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_attribute
))
++
n_attributes
;
}
xsd_node
=
xmlNewChild
(
parent
,
NULL
,
xs_element
,
NULL
);
assert
(
xsd_node
!=
NULL
);
switch
(
content
)
{
case
CONTENT_MIXED
:
case
CONTENT_ELTONLY
:
{
xmlNodePtr
xsd_base
;
xsd_type
=
xmlNewChild
(
xsd_node
,
NULL
,
xs_complexType
,
NULL
);
if
(
content
==
CONTENT_MIXED
)
xmlSetProp
(
xsd_type
,
xs_mixed
,
xs_true
);
if
(
is_open
)
xsd_base
=
xmlNewChild
(
xsd_type
,
NULL
,
xs_sequence
,
NULL
);
else
xsd_base
=
xsd_type
;
if
(
is_open
&&
n_elements
<
2
&&
!
n_groups
)
{
/* no specific sequence of elements we need,
just has to start with the right one, if any */
if
((
xdr_child
=
get_child
(
xdr
,
xs_element
)))
{
xsd_child
=
XDR_E_element
(
xdr_child
,
xsd_base
);
xmlUnsetProp
(
xsd_child
,
xs_maxOccurs
);
}
}
else
{
switch
(
order
)
{
case
ORDER_SEQ
:
xsd_child
=
xmlNewChild
(
xsd_base
,
NULL
,
xs_sequence
,
NULL
);
break
;
case
ORDER_MANY
:
xsd_child
=
xmlNewChild
(
xsd_base
,
NULL
,
xs_choice
,
NULL
);
xmlSetProp
(
xsd_child
,
xs_maxOccurs
,
xs_unbounded
);
break
;
case
ORDER_ONE
:
xsd_child
=
xmlNewChild
(
xsd_base
,
NULL
,
xs_all
,
NULL
);
break
;
}
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_element
))
XDR_E_element
(
xdr_child
,
xsd_child
);
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_group
))
XDR_E_group
(
xdr_child
,
xsd_child
);
}
}
if
(
n_attributes
)
{
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_attribute
))
XDR_E_attribute
(
xdr_child
,
xsd_type
);
}
}
if
(
is_open
)
{
add_any_child
(
xsd_base
,
TRUE
);
add_anyAttribute_child
(
xsd_type
);
}
}
break
;
case
CONTENT_TEXTONLY
:
{
if
(
is_open
)
{
xsd_type
=
xmlNewChild
(
xsd_node
,
NULL
,
xs_complexType
,
NULL
);
if
(
type
)
{
xsd_child
=
xmlNewChild
(
xsd_type
,
NULL
,
xs_simpleContent
,
NULL
);
xsd_child
=
xmlNewChild
(
xsd_child
,
NULL
,
xs_extension
,
NULL
);
str
=
xmlStrdup
(
DT_prefix
);
str
=
xmlStrcat
(
str
,
BAD_CAST
":"
);
str
=
xmlStrcat
(
str
,
type
);
xmlSetProp
(
xsd_child
,
xs_base
,
str
);
xmlFree
(
str
);
assert
(
dt_ns
!=
NULL
);
xmlSetNsProp
(
xsd_node
,
dt_ns
,
DT_prefix
,
type
);
}
else
{
xmlSetProp
(
xsd_type
,
xs_mixed
,
xs_true
);
xsd_child
=
xmlNewChild
(
xsd_type
,
NULL
,
xs_choice
,
NULL
);
xmlSetProp
(
xsd_child
,
xs_minOccurs
,
BAD_CAST
"0"
);
xmlSetProp
(
xsd_child
,
xs_maxOccurs
,
xs_unbounded
);
xsd_child
=
add_any_child
(
xsd_child
,
FALSE
);
xmlSetProp
(
xsd_child
,
xs_namespace
,
BAD_CAST
"##other"
);
xsd_child
=
xsd_type
;
}
if
(
n_attributes
)
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_attribute
))
XDR_E_attribute
(
xdr_child
,
xsd_child
);
}
xmlNewChild
(
xsd_child
,
NULL
,
xs_anyAttribute
,
NULL
);
}
else
if
(
!
n_attributes
)
{
if
(
type
)
{
str
=
xmlStrdup
(
DT_prefix
);
str
=
xmlStrcat
(
str
,
BAD_CAST
":"
);
str
=
xmlStrcat
(
str
,
type
);
xmlSetProp
(
xsd_node
,
xs_type
,
str
);
xmlFree
(
str
);
str
=
NULL
;
xmlSetNsProp
(
xsd_node
,
dt_ns
,
DT_prefix
,
type
);
}
else
{
xmlSetProp
(
xsd_node
,
xs_type
,
xs_xsd_string
);
}
}
else
{
xsd_type
=
xmlNewChild
(
xsd_node
,
NULL
,
xs_complexType
,
NULL
);
xsd_child
=
xmlNewChild
(
xsd_type
,
NULL
,
xs_simpleContent
,
NULL
);
xsd_child
=
xmlNewChild
(
xsd_child
,
NULL
,
xs_extension
,
NULL
);
xmlSetProp
(
xsd_child
,
xs_base
,
xs_xsd_string
);
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_attribute
))
XDR_E_attribute
(
xdr_child
,
xsd_child
);
}
}
}
break
;
case
CONTENT_EMPTY
:
/* not allowed with model="open" */
{
if
(
n_attributes
)
{
xsd_type
=
xmlNewChild
(
xsd_node
,
NULL
,
xs_complexType
,
NULL
);
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_attribute
))
XDR_E_attribute
(
xdr_child
,
xsd_type
);
}
}
else
{
xsd_type
=
xmlNewChild
(
xsd_node
,
NULL
,
xs_simpleType
,
NULL
);
xsd_child
=
xmlNewChild
(
xsd_type
,
NULL
,
xs_restriction
,
NULL
);
xmlSetProp
(
xsd_child
,
xs_base
,
xs_xsd_string
);
xsd_child
=
xmlNewChild
(
xsd_child
,
NULL
,
xs_length
,
NULL
);
xmlSetProp
(
xsd_child
,
xs_value
,
BAD_CAST
"0"
);
}
}
break
;
}
xmlFree
(
type
);
FOREACH_ATTR
(
xdr
,
xdr_attr
)
{
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_content
))
;
/* already handled */
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_name
))
XDR_A_name
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_type
)
&&
xdr_attr
->
ns
==
get_dt_ns
(
xdr
))
XDR_A_dt_type
(
xdr_attr
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_model
))
;
/* already handled */
else
if
(
xmlStrEqual
(
xdr_attr
->
name
,
xs_order
))
;
/* already handled */
else
xmlCopyProp
(
xsd_node
,
xdr_attr
);
}
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_attribute
))
;
/* already handled */
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_AttributeType
))
;
/* handled through XDR_E_attribute when parent is not <Schema> */
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_datatype
))
;
/* already handled */
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_description
))
XDR_E_description
(
xdr_child
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_element
))
;
/* already handled */
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_group
))
;
/* already handled */
else
FIXME
(
"unexpected child <%s>
\n
"
,
xdr_child
->
name
);
}
return
xsd_node
;
}
static
xmlNodePtr
XDR_E_Schema
(
xmlNodePtr
xdr
,
xmlNodePtr
parent
,
xmlChar
const
*
nsURI
)
{
xmlNodePtr
xsd_node
,
xdr_child
;
xmlNsPtr
ns
,
xdr_ns
;
xmlAttrPtr
xdr_attr
;
TRACE
(
"(%p, %p)
\n
"
,
xdr
,
parent
);
xsd_node
=
xmlNewDocNode
((
xmlDocPtr
)
parent
,
NULL
,
xs_schema
,
NULL
);
xmlDocSetRootElement
((
xmlDocPtr
)
parent
,
xsd_node
);
assert
(
xsd_node
!=
NULL
);
if
(
nsURI
&&
*
nsURI
)
xmlNewNs
(
xsd_node
,
nsURI
,
NULL
);
ns
=
xmlNewNs
(
xsd_node
,
XSD_href
,
XSD_prefix
);
assert
(
ns
!=
NULL
);
xmlSetNs
(
xsd_node
,
ns
);
if
(
nsURI
&&
*
nsURI
)
xmlSetProp
(
xsd_node
,
xs_targetNamespace
,
nsURI
);
FOREACH_NS
(
xdr
,
xdr_ns
)
{
/* TODO: special handling for dt namespace? */
assert
(
xdr_ns
->
href
!=
NULL
);
if
(
xmlStrEqual
(
xdr_ns
->
href
,
XDR_href
))
;
/* ignored */
else
if
(
xdr_ns
->
prefix
!=
NULL
)
xmlNewNs
(
xsd_node
,
xdr_ns
->
href
,
xdr_ns
->
prefix
);
else
FIXME
(
"unexpected default xmlns: %s
\n
"
,
xdr_ns
->
href
);
}
FOREACH_ATTR
(
xdr
,
xdr_attr
)
{
xmlCopyProp
(
xsd_node
,
xdr_attr
);
}
FOREACH_CHILD
(
xdr
,
xdr_child
)
{
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_AttributeType
))
XDR_E_AttributeType
(
xdr_child
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_description
))
XDR_E_description
(
xdr_child
,
xsd_node
);
else
if
(
xmlStrEqual
(
xdr_child
->
name
,
xs_ElementType
))
XDR_E_ElementType
(
xdr_child
,
xsd_node
);
else
FIXME
(
"unexpected child <%s>
\n
"
,
xdr_child
->
name
);
}
return
xsd_node
;
}
xmlDocPtr
XDR_to_XSD_doc
(
xmlDocPtr
xdr_doc
,
xmlChar
const
*
nsURI
)
{
xmlDocPtr
xsd_doc
=
xmlNewDoc
(
NULL
);
xmlNodePtr
root
;
TRACE
(
"(%p)
\n
"
,
xdr_doc
);
root
=
XDR_E_Schema
(
get_schema
((
xmlNodePtr
)
xdr_doc
),
(
xmlNodePtr
)
xsd_doc
,
nsURI
);
return
xsd_doc
;
}
#endif
/* HAVE_LIBXML2 */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment