polyxml 0.30.5__tar.gz → 0.30.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {polyxml-0.30.5 → polyxml-0.30.7}/Cargo.lock +6 -6
- {polyxml-0.30.5 → polyxml-0.30.7}/Cargo.toml +1 -1
- {polyxml-0.30.5 → polyxml-0.30.7}/PKG-INFO +1 -1
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/schema_parser/mod.rs +34 -5
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_schema_ir.rs +80 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/pyproject.toml +1 -1
- {polyxml-0.30.5 → polyxml-0.30.7}/README.md +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/Cargo.toml +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/README.md +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/benches/core_benchmarks.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/benches/support/tag_dispatch_fixtures.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/benches/tag_dispatch.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/cpp/mod.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/csharp/mod.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/go/mod.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/java/codec.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/java/mod.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/java/models.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/mod.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/python/aot.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/python/mod.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/rust/mod.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/codegen/typescript/mod.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/converters.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/error.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/ir/mod.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/ir/tarjan.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/json.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/lib.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/parser.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/schema.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/serializer.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/transcoder.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/src/value.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/fixtures/lexical_union.xsd +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/fixtures/mixed_content.xsd +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/fixtures/ts_mixed_content_inheritance.xsd +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_adversarial_identifiers.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_conformance.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_core.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_cpp_codegen.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_csharp_codegen.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_go_codegen.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_java_codegen.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_json.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_lexical_union_codegen.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_mixed_content.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_pattern_codegen.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_python_codegen.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_rust_codecs.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_rust_codegen.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_schema_audit.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_security.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_transcoder.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_ts_codegen.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_unbounded_choice.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/tests/test_xsi_type.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/Cargo.toml +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/README.md +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/benches/aot_vs_dataclass.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/src/lib.rs +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/tests/test_conformance.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/tests/test_generated_models.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/tests/test_json.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/tests/test_mixed_content.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/tests/test_polyxml.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-python/tests/test_xsi_type.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/python/polyxml/AGENT_GUIDE.md +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/python/polyxml/__init__.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/python/polyxml/compat/__init__.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/python/polyxml/compat/xsdata.py +0 -0
- {polyxml-0.30.5 → polyxml-0.30.7}/python/polyxml/py.typed +0 -0
|
@@ -608,7 +608,7 @@ dependencies = [
|
|
|
608
608
|
|
|
609
609
|
[[package]]
|
|
610
610
|
name = "polyxml"
|
|
611
|
-
version = "0.30.
|
|
611
|
+
version = "0.30.7"
|
|
612
612
|
dependencies = [
|
|
613
613
|
"criterion",
|
|
614
614
|
"heck",
|
|
@@ -629,14 +629,14 @@ dependencies = [
|
|
|
629
629
|
|
|
630
630
|
[[package]]
|
|
631
631
|
name = "polyxml-c"
|
|
632
|
-
version = "0.30.
|
|
632
|
+
version = "0.30.7"
|
|
633
633
|
dependencies = [
|
|
634
634
|
"polyxml",
|
|
635
635
|
]
|
|
636
636
|
|
|
637
637
|
[[package]]
|
|
638
638
|
name = "polyxml-cli"
|
|
639
|
-
version = "0.30.
|
|
639
|
+
version = "0.30.7"
|
|
640
640
|
dependencies = [
|
|
641
641
|
"clap",
|
|
642
642
|
"glob",
|
|
@@ -650,7 +650,7 @@ dependencies = [
|
|
|
650
650
|
|
|
651
651
|
[[package]]
|
|
652
652
|
name = "polyxml-js"
|
|
653
|
-
version = "0.30.
|
|
653
|
+
version = "0.30.7"
|
|
654
654
|
dependencies = [
|
|
655
655
|
"napi",
|
|
656
656
|
"napi-build",
|
|
@@ -660,7 +660,7 @@ dependencies = [
|
|
|
660
660
|
|
|
661
661
|
[[package]]
|
|
662
662
|
name = "polyxml-python"
|
|
663
|
-
version = "0.30.
|
|
663
|
+
version = "0.30.7"
|
|
664
664
|
dependencies = [
|
|
665
665
|
"lexical-core",
|
|
666
666
|
"polyxml",
|
|
@@ -670,7 +670,7 @@ dependencies = [
|
|
|
670
670
|
|
|
671
671
|
[[package]]
|
|
672
672
|
name = "polyxml-wasm"
|
|
673
|
-
version = "0.30.
|
|
673
|
+
version = "0.30.7"
|
|
674
674
|
dependencies = [
|
|
675
675
|
"polyxml",
|
|
676
676
|
"quick-xml",
|
|
@@ -189,7 +189,12 @@ impl XsdParser {
|
|
|
189
189
|
|
|
190
190
|
let mut ir = SchemaIR::new();
|
|
191
191
|
let mut target_namespace = None;
|
|
192
|
-
|
|
192
|
+
// The `xml` prefix is bound by XML itself, even when the schema omits
|
|
193
|
+
// an explicit xmlns:xml declaration (as Dublin Core's dc.xsd does).
|
|
194
|
+
let mut prefixes = HashMap::from([(
|
|
195
|
+
"xml".to_string(),
|
|
196
|
+
"http://www.w3.org/XML/1998/namespace".to_string(),
|
|
197
|
+
)]);
|
|
193
198
|
let mut buf = Vec::new();
|
|
194
199
|
|
|
195
200
|
// Pass 1: Parse root schema attributes and build prefix table
|
|
@@ -255,6 +260,11 @@ impl XsdParser {
|
|
|
255
260
|
}
|
|
256
261
|
}
|
|
257
262
|
merge_ir(&mut ir, sub_ir);
|
|
263
|
+
} else {
|
|
264
|
+
return Err(SchemaError::Resolution(format!(
|
|
265
|
+
"included schema not found: {}",
|
|
266
|
+
inc_path.display()
|
|
267
|
+
)));
|
|
258
268
|
}
|
|
259
269
|
}
|
|
260
270
|
}
|
|
@@ -366,6 +376,11 @@ impl XsdParser {
|
|
|
366
376
|
}
|
|
367
377
|
}
|
|
368
378
|
merge_ir(&mut ir, sub_ir);
|
|
379
|
+
} else {
|
|
380
|
+
return Err(SchemaError::Resolution(format!(
|
|
381
|
+
"included schema not found: {}",
|
|
382
|
+
inc_path.display()
|
|
383
|
+
)));
|
|
369
384
|
}
|
|
370
385
|
}
|
|
371
386
|
}
|
|
@@ -688,7 +703,10 @@ impl XsdParser {
|
|
|
688
703
|
if frame.kind == CompositorKind::Choice {
|
|
689
704
|
let choice_is_unbounded = frame.is_unbounded
|
|
690
705
|
|| compositor_stack.iter().any(|c| c.is_unbounded);
|
|
691
|
-
if choice_is_unbounded
|
|
706
|
+
if (choice_is_unbounded
|
|
707
|
+
|| (compositor_stack.is_empty() && base_type.is_some()))
|
|
708
|
+
&& !frame.choice_branches.is_empty()
|
|
709
|
+
{
|
|
692
710
|
let choice_name =
|
|
693
711
|
unique_type_name(ir, target_ns, &format!("{}Choice", name));
|
|
694
712
|
let choice_qname = QName::new(target_ns, choice_name);
|
|
@@ -700,10 +718,15 @@ impl XsdParser {
|
|
|
700
718
|
ir.add_type(TypeDef::Union(choice_def));
|
|
701
719
|
|
|
702
720
|
fields.truncate(frame.fields_start);
|
|
703
|
-
let
|
|
721
|
+
let field_base = if choice_is_unbounded {
|
|
722
|
+
"items"
|
|
723
|
+
} else {
|
|
724
|
+
"choice"
|
|
725
|
+
};
|
|
726
|
+
let mut item_field_name = field_base.to_string();
|
|
704
727
|
let mut counter = 2;
|
|
705
728
|
while fields.iter().any(|f| f.name == item_field_name) {
|
|
706
|
-
item_field_name = format!("
|
|
729
|
+
item_field_name = format!("{field_base}_{counter}");
|
|
707
730
|
counter += 1;
|
|
708
731
|
}
|
|
709
732
|
fields.push(FieldDef {
|
|
@@ -712,7 +735,13 @@ impl XsdParser {
|
|
|
712
735
|
namespace: None,
|
|
713
736
|
kind: FieldKind::Element,
|
|
714
737
|
type_ref: TypeRef::Named(choice_qname),
|
|
715
|
-
cardinality:
|
|
738
|
+
cardinality: if choice_is_unbounded {
|
|
739
|
+
Cardinality::unbounded(frame.min_occurs)
|
|
740
|
+
} else if frame.min_occurs == 0 {
|
|
741
|
+
Cardinality::optional_one()
|
|
742
|
+
} else {
|
|
743
|
+
Cardinality::required_one()
|
|
744
|
+
},
|
|
716
745
|
nillable: false,
|
|
717
746
|
default_value: None,
|
|
718
747
|
fixed_value: None,
|
|
@@ -6,6 +6,30 @@ use polyxml::ir::{
|
|
|
6
6
|
TypeDef, TypeRef,
|
|
7
7
|
};
|
|
8
8
|
use polyxml::schema_parser::XsdParser;
|
|
9
|
+
use tempfile::tempdir;
|
|
10
|
+
|
|
11
|
+
#[test]
|
|
12
|
+
fn missing_included_schema_is_an_error() {
|
|
13
|
+
let dir = tempdir().unwrap();
|
|
14
|
+
for (name, include) in [
|
|
15
|
+
("empty.xsd", r#"<xs:include schemaLocation="missing.xsd"/>"#),
|
|
16
|
+
(
|
|
17
|
+
"start.xsd",
|
|
18
|
+
r#"<xs:include schemaLocation="missing.xsd"></xs:include>"#,
|
|
19
|
+
),
|
|
20
|
+
] {
|
|
21
|
+
let path = dir.path().join(name);
|
|
22
|
+
std::fs::write(
|
|
23
|
+
&path,
|
|
24
|
+
format!(
|
|
25
|
+
r#"<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">{include}</xs:schema>"#
|
|
26
|
+
),
|
|
27
|
+
)
|
|
28
|
+
.unwrap();
|
|
29
|
+
let error = XsdParser::new().parse_file(&path).unwrap_err();
|
|
30
|
+
assert!(error.to_string().contains("missing.xsd"), "{error}");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
9
33
|
|
|
10
34
|
#[test]
|
|
11
35
|
fn consumed_child_subtrees_do_not_swallow_following_types() {
|
|
@@ -68,6 +92,62 @@ fn global_attribute_reference_uses_declared_type() {
|
|
|
68
92
|
);
|
|
69
93
|
}
|
|
70
94
|
|
|
95
|
+
#[test]
|
|
96
|
+
fn xml_prefix_is_available_without_explicit_declaration() {
|
|
97
|
+
let dir = tempdir().unwrap();
|
|
98
|
+
std::fs::write(
|
|
99
|
+
dir.path().join("xml.xsd"),
|
|
100
|
+
r#"<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3.org/XML/1998/namespace">
|
|
101
|
+
<xs:attribute name="lang" type="xs:language"/>
|
|
102
|
+
</xs:schema>"#,
|
|
103
|
+
)
|
|
104
|
+
.unwrap();
|
|
105
|
+
let main = dir.path().join("dc.xsd");
|
|
106
|
+
std::fs::write(
|
|
107
|
+
&main,
|
|
108
|
+
r#"<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:dc">
|
|
109
|
+
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
|
|
110
|
+
<xs:complexType name="SimpleLiteral"><xs:attribute ref="xml:lang"/></xs:complexType>
|
|
111
|
+
</xs:schema>"#,
|
|
112
|
+
)
|
|
113
|
+
.unwrap();
|
|
114
|
+
let ir = XsdParser::new().parse_file(&main).unwrap();
|
|
115
|
+
let TypeDef::Struct(literal) = &ir.types[&QName::new(Some("urn:dc"), "SimpleLiteral")] else {
|
|
116
|
+
panic!("expected SimpleLiteral struct");
|
|
117
|
+
};
|
|
118
|
+
assert_eq!(
|
|
119
|
+
literal.fields[0].type_ref,
|
|
120
|
+
TypeRef::Primitive(PrimitiveType::Language)
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
#[test]
|
|
125
|
+
fn derived_complex_type_keeps_base_and_bounded_choice() {
|
|
126
|
+
let xsd = r#"<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="urn:test" targetNamespace="urn:test">
|
|
127
|
+
<xs:complexType name="Base"><xs:attribute name="id" type="xs:string"/></xs:complexType>
|
|
128
|
+
<xs:complexType name="Node"><xs:complexContent><xs:extension base="t:Base"><xs:choice>
|
|
129
|
+
<xs:element name="left" type="xs:string"/><xs:element name="right" type="xs:int"/>
|
|
130
|
+
</xs:choice></xs:extension></xs:complexContent></xs:complexType>
|
|
131
|
+
<xs:complexType name="Child"><xs:complexContent><xs:extension base="t:Node">
|
|
132
|
+
<xs:attribute name="flag" type="xs:boolean"/>
|
|
133
|
+
</xs:extension></xs:complexContent></xs:complexType>
|
|
134
|
+
</xs:schema>"#;
|
|
135
|
+
let ir = XsdParser::new().parse_str(xsd).unwrap();
|
|
136
|
+
let TypeDef::Struct(node) = &ir.types[&QName::new(Some("urn:test"), "Node")] else {
|
|
137
|
+
panic!("derived choice must remain a struct");
|
|
138
|
+
};
|
|
139
|
+
assert_eq!(node.base_type, Some(QName::new(Some("urn:test"), "Base")));
|
|
140
|
+
assert_eq!(node.fields.len(), 1);
|
|
141
|
+
assert_eq!(node.fields[0].name, "choice");
|
|
142
|
+
let TypeRef::Named(choice_name) = &node.fields[0].type_ref else {
|
|
143
|
+
panic!("choice field must refer to a union");
|
|
144
|
+
};
|
|
145
|
+
let TypeDef::Union(choice) = &ir.types[choice_name] else {
|
|
146
|
+
panic!("choice field must refer to a union");
|
|
147
|
+
};
|
|
148
|
+
assert_eq!(choice.branches.len(), 2);
|
|
149
|
+
}
|
|
150
|
+
|
|
71
151
|
#[test]
|
|
72
152
|
fn test_parse_lexical_union_member_types_and_inline_members() {
|
|
73
153
|
let xsd = r#"<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="urn:test" targetNamespace="urn:test">
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{polyxml-0.30.5 → polyxml-0.30.7}/crates/polyxml-core/benches/support/tag_dispatch_fixtures.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|