17个版本 (6个重大更新)
0.9.1 | 2024年6月18日 |
---|---|
0.8.1 | 2024年4月6日 |
0.8.0 | 2024年3月16日 |
0.5.5 | 2023年9月26日 |
0.3.0 | 2022年6月2日 |
#294 in 编码
每月457次 下载
用于 8 个crate(2个直接使用)
23KB
273 行
xmlserde
xmlserde
是一个用于序列化和反序列化xml结构的工具。它专为 LogiSheets 设计,这是一个基于浏览器的电子表格应用程序。
您可以在 workbook
目录或 此处 查看使用细节。
如何使用 xmlserde
xmlserde
提供了一系列宏,足以满足大多数用例。要使用它们,您需要将以下crate包含在您的 Cargo.toml
文件中
xmlserde = 0.9
xmlserde_derives = 0.9
反序列化
从反序列化开始将更容易了解 xmlserde
。
给定以下xml结构
<person age ="16">Tom</person>
我们可以使用以下代码进行反序列化
use xmlserde_derives: XmlDerserialize
#[derive(XmlDeserialize)]
#[xmlserde(root = b"person")]
pub struct Person {
#[xmlserde(name=b"age", ty="attr")]
pub age: u8,
#[xmlserde(ty ="text")]
pub name: String,
}
fn deserialize_person() {
use xmlserde::xml_deserialize_from_str;
let s = r#"<person age ="16">Tom</person>"#;
let p = xml_deserialize_from_str(s).unwrap();
assert_eq!(p.age, 16);
assert_eq!(p.name, "Tom");
}
您应该在反序列化器查找值的地方声明。
常见的类型有 attr、text 和 child。在上面的例子中,我们指示程序进入名为 person
的标签(使用 xml_deserialize_from_str
),并搜索具有键 age
的属性。此外,它还指定文本元素的内容表示字段的值 name
。
您可以使用类似 #[xmlserde(root = b"person")]
的注释来指定xmlserde的序列化/反序列化输入元素,从而告诉程序 person
元素是serde操作的根。
以下是一个演示如何反序列化嵌套XML元素的示例
#[derive(XmlDeserialize)]
#[xmlserde(root = b"person")]
pub struct Person {
#[xmlserde(name=b"age", ty="attr")]
pub age: u8,
#[xmlserde(name = b"lefty", ty ="attr", default = "default_lefty")]
pub lefty: bool,
#[xmlserde(name = b"name", ty ="child")]
pub name: Name,
}
#[derive(XmlDeserialize)]
pub struct Name {
#[xmlserde(name = b"zh", ty ="attr")]
pub zh: String,
#[xmlserde(name = b"en", ty ="attr")]
pub en: String,
}
fn deserialize_person() {
use xmlserde::xml_deserialize_from_str;
let s = r#"<person age ="16"><name zh="汤姆", en="Tom"/></person>"#;
let p = xml_deserialize_from_str(s).unwrap();
assert_eq!(p.age, 16);
assert_eq!(p.name.en, "Tom");
assert_eq!(p.lefty, false);
}
fn default_lefty() -> bool { false }
在给定示例中,我们指定从标记为 <name>
的子元素中提取 name
字段的值。因此,程序将进入 <name>
元素并进行递归反序列化。
此外,我们指定如果反序列化器没有找到 lefty
的值,则应将 lefty
的默认值设置为 false。
Vec
我们支持反序列化类型为 std::Vec<T: XmlDeserialize>
的字段。
#[derive(XmlDeserialize)]
pub struct Pet {
// Fields
}
#[derive(XmlDeserialize)]
#[xmlserde(root = b"person")]
pub struct Person {
#[xmlserde(name = b"petCount", ty = "attr")]
pub pet_count: u8,
#[xmlserde(name = b"pet", ty = "child")]
pub pets: Vec<Pet>
}
当反序列化器找到 pet 元素时,它将知道这是一个 pets 的元素。您甚至可以使用以下方式分配 Vec
的容量
#[xmlserde(name = b"pet", ty="child", vec_size=3)]
如果容量来自 attr,则可以
#[xmlserde(name = b"pet", ty="child", vec_size="pet_count")]
Enum
我们提供了两种反序列化 Enum
的模式。
#[derive(XmlSerialize, XmlDeserialize)]
enum TestEnum {
#[xmlserde(name = b"testA")]
TestA(TestA),
#[xmlserde(name = b"testB")]
TestB(TestB),
}
#[derive(XmlSerialize, XmlDeserialize)]
#[xmlserde(root = b"personA")]
pub struct PersonA {
#[xmlserde(name = b"e", ty = "child")]
pub e: TestEnum
// Other fields
}
#[derive(XmlSerialize, XmlDeserialize)]
#[xmlserde(root = b"personB")]
pub struct PersonB {
#[xmlserde(ty = "untag")]
pub dummy: TestEnum
// Other fields
}
PersonA 可以用于反序列化如下 XML 结构
<personA><e><testA/></e></personA>
或
<personA><e><testB/></e></personA>
而 PersonB 可以用于反序列化如下 XML
<personB><testA/></personB>
或
<personB><testB/></personB>
您可以使用 untag 将 Option<T> 或 Vec<T>(其中 T 是一个 Enum)转换为字符串类型。
这意味着以下示例是合法的
#[derive(XmlSerialize, XmlDeserialize)]
#[xmlserde(root = b"personB")]
pub struct PersonB {
#[xmlserde(ty = "untag")]
pub dummy1: Enum1,
#[xmlserde(ty = "untag")]
pub dummy2: Option<Enum2>,
#[xmlserde(ty = "untag")]
pub dummy3: Vec<Enum3>,
// Other fields
}
未解析
在某些情况下,当某些 XML 元素不是立即相关的,但您希望为了将来的序列化而保留它们时,我们提供了 Unparsed
结构来实现这一目的。
use xmlserde::Unparsed;
#[derive(XmlDeserialize)]
pub struct Person {
#[xmlserde(name = b"educationHistory", ty = "child")]
pub education_history: Unparsed,
}
序列化
序列化在很大程度上与反序列化相似。但是,有几个关键特性需要考虑。
-
默认值将跳过序列化。如果它是一个 struct,则应该实现
Eq
特性。 -
如果一个结构没有 child 或 text,则序列化的结果将如下所示
<tag attr1="value1"/>
自定义 xmlserde
xmlserde
提供了 XmlSerialize
和 XmlDeserialize
特性,允许您通过实现这些特性来指定结构的序列化和反序列化行为。目前,仅允许使用内置类型作为属性。要启用自定义类型用于属性,可以在这些类型上实现 XmlValue
特性。
字符串类型的 Enum
xmlserde
还提供了一个名为 xml_serde_enum
的宏,用于将字符串类型的 enum
序列化。
xml_serde_enum
定义了一个 enum
并指定了序列化和反序列化的行为。
use xmlserde::xml_serde_enum;
xml_serde_enum!{
#[derive(Debug)]
Gender {
Male => "male",
Female => "female",
}
}
依赖项
~1.5MB
~29K SLoC