Skip to main content

easyofd_reader/tools/
namespace_modifier.rs

1//! 命名空间变更工具。
2//!
3//! 对应 Java: org.ofdrw.reader.tools.NameSpaceModifier
4//!
5//! 已废弃:Java 原始类标记为 `@Deprecated`。
6//! Rust 版提供 OFD XML 命名空间标准化功能。
7
8/// OFD 标准命名空间 URI。
9pub const OFD_NAMESPACE: &str = "http://www.ofdspec.org/2016";
10
11/// OFD 命名空间前缀。
12pub const OFD_PREFIX: &str = "ofd";
13
14/// 命名空间变更器。
15///
16/// 对应 Java: `org.ofdrw.reader.tools.NameSpaceModifier`
17///
18/// **废弃**:Java 原始类标记为 `@Deprecated`,
19/// 建议使用 `easyofd_package` 中的命名空间处理工具。
20///
21/// 将 XML 内容中的非标准命名空间替换为标准 OFD 命名空间。
22#[derive(Debug, Clone)]
23#[deprecated(since = "1.0.0", note = "使用 easyofd_package 中的命名空间工具替代")]
24pub struct NamespaceModifier {
25    /// 期望变更到的命名空间 URI。
26    expect_ns: String,
27}
28
29#[allow(deprecated)]
30impl NamespaceModifier {
31    /// 使用默认 OFD 命名空间创建变更器。
32    #[must_use]
33    pub fn new() -> Self {
34        Self {
35            expect_ns: OFD_NAMESPACE.to_string(),
36        }
37    }
38
39    /// 使用指定命名空间创建变更器。
40    #[must_use]
41    pub fn with_namespace(namespace: impl Into<String>) -> Self {
42        Self {
43            expect_ns: namespace.into(),
44        }
45    }
46
47    /// 获取期望的命名空间 URI。
48    #[must_use]
49    pub fn expected_namespace(&self) -> &str {
50        &self.expect_ns
51    }
52
53    /// 替换 XML 字符串中的命名空间声明。
54    ///
55    /// 将所有 `xmlns:xxx="..."` 声明替换为目标命名空间。
56    #[must_use]
57    pub fn modify_xml(&self, xml: &str) -> String {
58        // 简化实现:替换 xmlns:ofd="..." 声明中的 URI
59        let pattern = r#"xmlns:ofd=""#;
60        if let Some(start) = xml.find(pattern) {
61            let after_prefix = start + pattern.len();
62            if let Some(end) = xml[after_prefix..].find('"') {
63                let mut result = String::with_capacity(xml.len());
64                result.push_str(&xml[..after_prefix]);
65                result.push_str(&self.expect_ns);
66                result.push_str(&xml[after_prefix + end..]);
67                return result;
68            }
69        }
70        xml.to_string()
71    }
72}
73
74#[allow(deprecated)]
75impl Default for NamespaceModifier {
76    fn default() -> Self {
77        Self::new()
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    #[allow(deprecated)]
84    use super::*;
85
86    #[test]
87    #[allow(deprecated)]
88    fn test_namespace_modifier_new() {
89        let modifier = NamespaceModifier::new();
90        assert_eq!(modifier.expected_namespace(), OFD_NAMESPACE);
91    }
92
93    #[test]
94    #[allow(deprecated)]
95    fn test_namespace_modifier_with_namespace() {
96        let modifier = NamespaceModifier::with_namespace("http://custom.ns");
97        assert_eq!(modifier.expected_namespace(), "http://custom.ns");
98    }
99
100    #[test]
101    #[allow(deprecated)]
102    fn test_modify_xml() {
103        let xml = r#"<?xml version="1.0"?>
104<ofd:OFD xmlns:ofd="http://wrong.namespace">
105  <ofd:DocBody/>
106</ofd:OFD>"#;
107        let modifier = NamespaceModifier::new();
108        let result = modifier.modify_xml(xml);
109        assert!(result.contains(OFD_NAMESPACE));
110        assert!(!result.contains("wrong.namespace"));
111    }
112
113    #[test]
114    #[allow(deprecated)]
115    fn test_modify_xml_no_change() {
116        let xml = r#"<ofd:OFD xmlns:ofd="http://www.ofdspec.org/2016"/>"#;
117        let modifier = NamespaceModifier::new();
118        let result = modifier.modify_xml(xml);
119        assert!(result.contains(OFD_NAMESPACE));
120    }
121
122    #[test]
123    #[allow(deprecated)]
124    fn test_modify_xml_no_namespace() {
125        let xml = "<root><child/></root>";
126        let modifier = NamespaceModifier::new();
127        let result = modifier.modify_xml(xml);
128        assert_eq!(result, xml);
129    }
130}