use mf_core::{XmlSchemaParser, XmlSchemaResult, EditorOptionsBuilder};
use mf_model::schema::Schema;
fn main() -> XmlSchemaResult<()> {
println!("=== XML Schema 与 Runtime 集成示例 ===\n");
schema_runtime_integration()?;
extensions_runtime_integration()?;
println!("\n=== 集成示例执行完成 ===");
Ok(())
}
fn schema_runtime_integration() -> XmlSchemaResult<()> {
println!("1. Schema与Runtime集成:");
let xml = r#"
<?xml version="1.0" encoding="UTF-8"?>
<schema top_node="doc">
<nodes>
<node name="doc" group="block">
<desc>文档根节点</desc>
<content>paragraph+</content>
<marks>_</marks>
<attrs>
<attr name="title" default="New Document"/>
<attr name="author"/>
</attrs>
</node>
<node name="paragraph" group="block">
<desc>段落节点</desc>
<content>text*</content>
<marks>strong em link</marks>
<attrs>
<attr name="align" default="left"/>
<attr name="indent" default="0"/>
</attrs>
</node>
<node name="heading" group="block">
<desc>标题节点</desc>
<content>text*</content>
<marks>strong em</marks>
<attrs>
<attr name="level" default="1"/>
</attrs>
</node>
<node name="text">
<desc>文本节点</desc>
</node>
</nodes>
<marks>
<mark name="strong" group="formatting">
<desc>粗体标记</desc>
<spanning>true</spanning>
</mark>
<mark name="em" group="formatting">
<desc>斜体标记</desc>
<spanning>true</spanning>
</mark>
<mark name="link" group="link">
<desc>链接标记</desc>
<spanning>false</spanning>
<attrs>
<attr name="href"/>
<attr name="title"/>
</attrs>
</mark>
</marks>
</schema>
"#;
let schema_spec = XmlSchemaParser::parse_from_str(xml)?;
println!(" ✅ XML Schema解析成功");
let schema = Schema::compile(schema_spec).map_err(|e| {
mf_core::XmlSchemaError::InvalidNodeDefinition(format!(
"Schema编译失败: {e}"
))
})?;
println!(" ✅ Schema编译成功");
let factory = schema.factory();
let (nodes, marks) = factory.definitions();
println!(" - 节点类型数量: {}", nodes.len());
println!(" - 标记类型数量: {}", marks.len());
println!(
" - 顶级节点: {:?}",
schema.top_node_type.as_ref().map(|n| &n.name)
);
for (name, node_type) in nodes {
println!(
" - 节点 '{}': 组={:?}, 内容={:?}",
name, node_type.spec.group, node_type.spec.content
);
}
for (name, mark_type) in marks {
println!(
" - 标记 '{}': 组={:?}, spanning={:?}",
name, mark_type.spec.group, mark_type.spec.spanning
);
}
Ok(())
}
fn extensions_runtime_integration() -> XmlSchemaResult<()> {
println!("\n2. Extensions与Runtime集成:");
let xml = r#"
<?xml version="1.0" encoding="UTF-8"?>
<schema top_node="doc">
<nodes>
<node name="doc" group="block">
<desc>文档根节点</desc>
<content>paragraph+</content>
</node>
<node name="paragraph" group="block">
<desc>段落节点</desc>
<content>text*</content>
<marks>strong</marks>
</node>
<node name="text">
<desc>文本节点</desc>
</node>
</nodes>
<marks>
<mark name="strong" group="formatting">
<desc>粗体标记</desc>
<spanning>true</spanning>
</mark>
</marks>
</schema>
"#;
let extensions = XmlSchemaParser::parse_to_extensions(xml)?;
println!(" ✅ Extensions解析成功,数量: {}", extensions.len());
let options = EditorOptionsBuilder::new()
.extensions(extensions)
.history_limit(100)
.build();
println!(" ✅ RuntimeOptions创建成功");
println!(" - Extensions数量: {}", options.get_extensions().len());
println!(" - 历史记录限制: {:?}", options.get_history_limit());
let extensions = options.get_extensions();
let mut node_names = Vec::new();
let mut mark_names = Vec::new();
for ext in &extensions {
match ext {
mf_core::types::Extensions::N(node) => {
node_names.push(node.get_name().to_string());
},
mf_core::types::Extensions::M(mark) => {
mark_names.push(mark.get_name().to_string());
},
mf_core::types::Extensions::E(_) => {
},
}
}
println!(" - 节点类型: {node_names:?}");
println!(" - 标记类型: {mark_names:?}");
Ok(())
}
#[allow(dead_code)]
fn multi_file_schema_composition() -> XmlSchemaResult<()> {
println!("\n3. 多文件Schema组合:");
let base_schema_xml = r#"
<?xml version="1.0" encoding="UTF-8"?>
<schema top_node="doc">
<nodes>
<node name="doc">
<content>paragraph+</content>
</node>
<node name="paragraph">
<content>text*</content>
</node>
<node name="text">
<desc>文本节点</desc>
</node>
</nodes>
</schema>
"#;
let extension_schema_xml = r#"
<?xml version="1.0" encoding="UTF-8"?>
<schema>
<nodes>
<node name="heading" group="block">
<desc>标题节点</desc>
<content>text*</content>
<attrs>
<attr name="level" default="1"/>
</attrs>
</node>
</nodes>
<marks>
<mark name="strong">
<desc>粗体标记</desc>
<spanning>true</spanning>
</mark>
</marks>
</schema>
"#;
let mut base_spec = XmlSchemaParser::parse_from_str(base_schema_xml)?;
println!(" ✅ 基础Schema解析成功");
let ext_spec = XmlSchemaParser::parse_from_str(extension_schema_xml)?;
println!(" ✅ 扩展Schema解析成功");
for (name, node_spec) in ext_spec.nodes {
base_spec.nodes.insert(name, node_spec);
}
for (name, mark_spec) in ext_spec.marks {
base_spec.marks.insert(name, mark_spec);
}
println!(" ✅ Schema合并完成");
println!(" - 最终节点数量: {}", base_spec.nodes.len());
println!(" - 最终标记数量: {}", base_spec.marks.len());
let _schema = Schema::compile(base_spec).map_err(|e| {
mf_core::XmlSchemaError::InvalidNodeDefinition(format!(
"合并Schema编译失败: {e}"
))
})?;
println!(" ✅ 合并Schema编译成功");
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_schema_runtime_integration() {
assert!(schema_runtime_integration().is_ok());
}
#[test]
fn test_extensions_runtime_integration() {
assert!(extensions_runtime_integration().is_ok());
}
#[test]
fn test_multi_file_composition() {
assert!(multi_file_schema_composition().is_ok());
}
}