polyxml 0.33.11__tar.gz → 0.34.0__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.
Files changed (84) hide show
  1. {polyxml-0.33.11 → polyxml-0.34.0}/Cargo.lock +6 -6
  2. {polyxml-0.33.11 → polyxml-0.34.0}/Cargo.toml +1 -1
  3. {polyxml-0.33.11 → polyxml-0.34.0}/PKG-INFO +1 -1
  4. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/java/mod.rs +18 -6
  5. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/java/models.rs +20 -0
  6. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/ir/mod.rs +3 -0
  7. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/schema_parser/mod.rs +7 -0
  8. polyxml-0.34.0/crates/polyxml-core/src/schema_parser/upa.rs +780 -0
  9. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_java_codegen.rs +47 -0
  10. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_schema_ir.rs +3 -2
  11. polyxml-0.34.0/crates/polyxml-core/tests/test_upa.rs +185 -0
  12. {polyxml-0.33.11 → polyxml-0.34.0}/pyproject.toml +1 -1
  13. {polyxml-0.33.11 → polyxml-0.34.0}/README.md +0 -0
  14. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/Cargo.toml +0 -0
  15. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/README.md +0 -0
  16. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/benches/core_benchmarks.rs +0 -0
  17. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/benches/support/tag_dispatch_fixtures.rs +0 -0
  18. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/benches/tag_dispatch.rs +0 -0
  19. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/cpp/mod.rs +0 -0
  20. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/csharp/mod.rs +0 -0
  21. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/go/mod.rs +0 -0
  22. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/java/codec.rs +0 -0
  23. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/mod.rs +0 -0
  24. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/python/aot.rs +0 -0
  25. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/python/mod.rs +0 -0
  26. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/rust/mod.rs +0 -0
  27. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/codegen/typescript/mod.rs +0 -0
  28. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/converters.rs +0 -0
  29. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/error.rs +0 -0
  30. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/integer.rs +0 -0
  31. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/ir/chunker.rs +0 -0
  32. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/ir/particle.rs +0 -0
  33. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/ir/tarjan.rs +0 -0
  34. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/json.rs +0 -0
  35. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/lib.rs +0 -0
  36. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/parser.rs +0 -0
  37. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/schema.rs +0 -0
  38. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/serializer.rs +0 -0
  39. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/transcoder.rs +0 -0
  40. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/src/value.rs +0 -0
  41. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/fixtures/lexical_union.xsd +0 -0
  42. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/fixtures/mixed_content.xsd +0 -0
  43. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/fixtures/ts_mixed_content_inheritance.xsd +0 -0
  44. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_adversarial_identifiers.rs +0 -0
  45. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_any_attribute.rs +0 -0
  46. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_any_element.rs +0 -0
  47. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_conformance.rs +0 -0
  48. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_core.rs +0 -0
  49. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_cpp_codegen.rs +0 -0
  50. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_csharp_codegen.rs +0 -0
  51. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_go_codegen.rs +0 -0
  52. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_json.rs +0 -0
  53. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_lexical_lists.rs +0 -0
  54. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_lexical_union_codegen.rs +0 -0
  55. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_mixed_content.rs +0 -0
  56. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_pattern_codegen.rs +0 -0
  57. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_python_codegen.rs +0 -0
  58. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_qualified_attributes.rs +0 -0
  59. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_rust_codecs.rs +0 -0
  60. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_rust_codegen.rs +0 -0
  61. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_schema_audit.rs +0 -0
  62. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_security.rs +0 -0
  63. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_temporal_union.rs +0 -0
  64. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_transcoder.rs +0 -0
  65. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_ts_codegen.rs +0 -0
  66. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_ubl_csharp.rs +0 -0
  67. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_unbounded_choice.rs +0 -0
  68. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_value_constraints.rs +0 -0
  69. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-core/tests/test_xsi_type.rs +0 -0
  70. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/Cargo.toml +0 -0
  71. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/README.md +0 -0
  72. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/benches/aot_vs_dataclass.py +0 -0
  73. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/src/lib.rs +0 -0
  74. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/tests/test_conformance.py +0 -0
  75. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/tests/test_generated_models.py +0 -0
  76. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/tests/test_json.py +0 -0
  77. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/tests/test_mixed_content.py +0 -0
  78. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/tests/test_polyxml.py +0 -0
  79. {polyxml-0.33.11 → polyxml-0.34.0}/crates/polyxml-python/tests/test_xsi_type.py +0 -0
  80. {polyxml-0.33.11 → polyxml-0.34.0}/python/polyxml/AGENT_GUIDE.md +0 -0
  81. {polyxml-0.33.11 → polyxml-0.34.0}/python/polyxml/__init__.py +0 -0
  82. {polyxml-0.33.11 → polyxml-0.34.0}/python/polyxml/compat/__init__.py +0 -0
  83. {polyxml-0.33.11 → polyxml-0.34.0}/python/polyxml/compat/xsdata.py +0 -0
  84. {polyxml-0.33.11 → polyxml-0.34.0}/python/polyxml/py.typed +0 -0
@@ -608,7 +608,7 @@ dependencies = [
608
608
 
609
609
  [[package]]
610
610
  name = "polyxml"
611
- version = "0.33.11"
611
+ version = "0.34.0"
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.33.11"
632
+ version = "0.34.0"
633
633
  dependencies = [
634
634
  "polyxml",
635
635
  ]
636
636
 
637
637
  [[package]]
638
638
  name = "polyxml-cli"
639
- version = "0.33.11"
639
+ version = "0.34.0"
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.33.11"
653
+ version = "0.34.0"
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.33.11"
663
+ version = "0.34.0"
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.33.11"
673
+ version = "0.34.0"
674
674
  dependencies = [
675
675
  "polyxml",
676
676
  "quick-xml",
@@ -3,7 +3,7 @@ resolver = "2"
3
3
  members = ["crates/polyxml-core", "crates/polyxml-python"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.33.11"
6
+ version = "0.34.0"
7
7
  edition = "2021"
8
8
  rust-version = "1.80"
9
9
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: polyxml
3
- Version: 0.33.11
3
+ Version: 0.34.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -24,6 +24,8 @@ pub enum JavaBackend {
24
24
  Standard,
25
25
  /// Jackson-annotated records for Spring Boot / enterprise JSON+XML binding.
26
26
  Jackson,
27
+ /// Jackson 3 annotations for Spring Boot 4 JSON+XML binding.
28
+ Jackson3,
27
29
  }
28
30
 
29
31
  impl JavaBackend {
@@ -31,12 +33,13 @@ impl JavaBackend {
31
33
  match s.to_lowercase().trim() {
32
34
  "standard" | "std" | "default" => Some(Self::Standard),
33
35
  "jackson" | "spring" | "spring-boot" | "enterprise" => Some(Self::Jackson),
36
+ "jackson3" | "jackson-3" | "jackson_3" | "spring-boot-4" => Some(Self::Jackson3),
34
37
  _ => None,
35
38
  }
36
39
  }
37
40
 
38
41
  pub fn is_jackson(self) -> bool {
39
- matches!(self, Self::Jackson)
42
+ matches!(self, Self::Jackson | Self::Jackson3)
40
43
  }
41
44
  }
42
45
 
@@ -365,7 +368,11 @@ impl JavaCodegen {
365
368
  if self.options.backend.is_jackson() {
366
369
  out.push('\n');
367
370
  out.push_str("import com.fasterxml.jackson.annotation.*;\n");
368
- out.push_str("import com.fasterxml.jackson.dataformat.xml.annotation.*;\n");
371
+ if self.options.backend == JavaBackend::Jackson3 {
372
+ out.push_str("import tools.jackson.dataformat.xml.annotation.*;\n");
373
+ } else {
374
+ out.push_str("import com.fasterxml.jackson.dataformat.xml.annotation.*;\n");
375
+ }
369
376
  }
370
377
 
371
378
  out.push('\n');
@@ -445,6 +452,7 @@ impl JavaCodegen {
445
452
  let jackson = self.options.backend.is_jackson();
446
453
 
447
454
  // Jackson class-level annotations
455
+ self.emit_jackson_property_order(out, s, ir, indent);
448
456
  if jackson {
449
457
  let _ = writeln!(out, "{}@JsonIgnoreProperties(ignoreUnknown = true)", indent);
450
458
  let _ = writeln!(out, "{}@JsonInclude(JsonInclude.Include.NON_EMPTY)", indent);
@@ -488,10 +496,14 @@ impl JavaCodegen {
488
496
  .as_deref()
489
497
  .map(|ns| format!(", namespace = {:?}", ns))
490
498
  .unwrap_or_default();
491
- annotations.push(format!(
492
- "@JacksonXmlProperty(localName = {:?}, isAttribute = {}{})",
493
- field.xml_name, is_attr, ns_part
494
- ));
499
+ if field.kind == crate::ir::FieldKind::Text {
500
+ annotations.push("@JacksonXmlText".to_string());
501
+ } else {
502
+ annotations.push(format!(
503
+ "@JacksonXmlProperty(localName = {:?}, isAttribute = {}{})",
504
+ field.xml_name, is_attr, ns_part
505
+ ));
506
+ }
495
507
 
496
508
  // List fields: @JacksonXmlElementWrapper(useWrapping = false)
497
509
  if is_list {
@@ -3,6 +3,25 @@ use crate::codegen::flatten_fields;
3
3
  use crate::ir::{FieldDef, FieldKind};
4
4
 
5
5
  impl JavaCodegen {
6
+ pub(super) fn emit_jackson_property_order(
7
+ &self,
8
+ out: &mut String,
9
+ s: &StructDef,
10
+ ir: &SchemaIR,
11
+ indent: &str,
12
+ ) {
13
+ if self.options.backend == JavaBackend::Jackson3 {
14
+ // Jackson 3 sorts properties alphabetically by default. XML
15
+ // sequences must instead retain the schema's declaration order.
16
+ let names = flatten_fields(s, ir)
17
+ .into_iter()
18
+ .map(|field| format!("{:?}", field.xml_name))
19
+ .collect::<Vec<_>>()
20
+ .join(", ");
21
+ let _ = writeln!(out, "{indent}@JsonPropertyOrder({{{names}}})");
22
+ }
23
+ }
24
+
6
25
  pub(super) fn emit_value_class(
7
26
  &self,
8
27
  out: &mut String,
@@ -141,6 +160,7 @@ impl JavaCodegen {
141
160
  if let Some(doc) = &s.documentation {
142
161
  self.emit_docstring(out, doc, indent);
143
162
  }
163
+ self.emit_jackson_property_order(out, s, ir, indent);
144
164
  if self.options.backend.is_jackson() {
145
165
  let _ = writeln!(out, "{indent}@JsonIgnoreProperties(ignoreUnknown = true)\n{indent}@JsonInclude(JsonInclude.Include.NON_NULL)\n{indent}@JacksonXmlRootElement(localName = {:?}, namespace = {:?})", s.qname.local, s.qname.namespace.as_deref().unwrap_or(""));
146
166
  // Bind the explicitly annotated fields only; avoids duplicate XML properties after bean name normalization.
@@ -484,6 +484,9 @@ pub struct SchemaIR {
484
484
  pub ordered_types: std::collections::BTreeSet<QName>,
485
485
  #[serde(default)]
486
486
  pub content_models: BTreeMap<QName, Particle>,
487
+ /// Source particle identity retained for schema-level XSD 1.0 UPA checks.
488
+ #[serde(default)]
489
+ pub upa_documents: Vec<crate::schema_parser::upa::Document>,
487
490
  /// Type owners outside the module currently being emitted. Definitions
488
491
  /// remain in `types` so generators can resolve their field semantics.
489
492
  #[serde(default)]
@@ -1,3 +1,4 @@
1
+ pub mod upa;
1
2
  use std::collections::{BTreeMap, HashMap, HashSet};
2
3
  use std::fs;
3
4
  use std::path::{Path, PathBuf};
@@ -185,6 +186,7 @@ impl XsdParser {
185
186
  if self.frame_depth == 0 {
186
187
  resolve_global_field_refs(&mut ir);
187
188
  validate_type_references(&ir, xml)?;
189
+ upa::validate(&ir)?;
188
190
  ir.content_models.retain(|_, model| {
189
191
  model.has_choice()
190
192
  || model.has_repeated_sequence()
@@ -214,6 +216,7 @@ impl XsdParser {
214
216
  reader.config_mut().trim_text(true);
215
217
 
216
218
  let mut ir = SchemaIR::new();
219
+ ir.upa_documents.push(upa::Document::parse(xml)?);
217
220
  let mut target_namespace = None;
218
221
  // The `xml` prefix is bound by XML itself, even when the schema omits
219
222
  // an explicit xmlns:xml declaration (as Dublin Core's dc.xsd does).
@@ -2329,6 +2332,9 @@ fn unique_type_name(ir: &SchemaIR, target_ns: Option<&str>, base: &str) -> Strin
2329
2332
  /// Rewrite every namespace-less QName in the IR to `ns`. Used for chameleon
2330
2333
  /// includes, whose components adopt the including schema's target namespace.
2331
2334
  fn rekey_to_namespace(ir: &mut SchemaIR, ns: &str) {
2335
+ for document in &mut ir.upa_documents {
2336
+ document.adopt_namespace(ns);
2337
+ }
2332
2338
  ir.target_namespace = Some(ns.to_string());
2333
2339
  ir.abstract_elements = std::mem::take(&mut ir.abstract_elements)
2334
2340
  .into_iter()
@@ -2548,6 +2554,7 @@ fn collect_chain_patterns(ir: &SchemaIR, q: &QName, visited: &mut HashSet<QName>
2548
2554
  }
2549
2555
 
2550
2556
  fn merge_ir(dest: &mut SchemaIR, src: SchemaIR) {
2557
+ dest.upa_documents.extend(src.upa_documents);
2551
2558
  dest.abstract_elements.extend(src.abstract_elements);
2552
2559
  dest.ordered_types.extend(src.ordered_types);
2553
2560
  dest.content_models.extend(src.content_models);