Parsing xml Initial vector

Hi,
i'm parsing a new file xml as follows :

<GC version="x.x.x" endianness="little" db_path="xxx/yyy/zzz">
	<Sys>
		<Area>
			<name>AAA</name>
			<module>BBB</module>
		</Area>
	</Sys>
	<Sys>
		<Area>
			<name>AAA</name>
			<module>BBB</module>
		</Area>
	</Sys>
</GC>

and i suppose that this is the correct structure:

#[derive(Debug, Deserialize)]
pub struct GC{
        version : i32,
        endianness : String,
       db_path : String,
    GC: Vec<Sys>,
}

#[derive(Debug, Deserialize)]
struct Sys{
    sys: Vec<Area>,
}

#[derive(Debug, Deserialize)]
struct Area {
    Area: Vec<Group>,
}

#[derive(Debug, Deserialize)]
struct Group {
    //#[serde(rename = "v")]
    name: Vec<Name>,
    module: Vec<Module>,
}

#[derive(Debug, Deserialize)]
struct Name{
    //name: String,
    #[serde(rename = "$value")]
    value: String,
}

#[derive(Debug, Deserialize)]
struct Module{
    //name: String,
    #[serde(rename = "$value")]
    value: String,
}

but it isn't . i don't know where i'm going wrong

There is no Group tag in your xml, so Area should have the fields of Group directly. Also you need to use the #[serde(rename = "$value")] tag for all fields you intend to store untagged values in. Currently you only use that attribute for scalar values, but it also applies to vectors.

This works parsing your xml file:

/*
[dependencies]
serde = { version = "1", features = ["derive"] }
serde-xml-rs = "*"
*/
#![allow(dead_code)]

use serde::Deserialize;
use serde_xml_rs;

#[derive(Debug, Deserialize)]
pub struct GC {
    version: String,
    endianness: String,
    db_path: String,
    #[serde(rename = "$value")]
    gc: Vec<Sys>,
}

#[derive(Debug, Deserialize)]
struct Sys {
    #[serde(rename = "$value")]
    sys: Vec<Area>,
}

#[derive(Debug, Deserialize)]
struct Area {
    name: Vec<Name>,
    module: Vec<Module>,
}

#[derive(Debug, Deserialize)]
struct Name {
    #[serde(rename = "$value")]
    value: String,
}

#[derive(Debug, Deserialize)]
struct Module {
    #[serde(rename = "$value")]
    value: String,
}

fn main() {
    let xml = r#"
    <GC version="x.x.x" endianness="little" db_path="xxx/yyy/zzz">
	<Sys>
		<Area>
			<name>AAA</name>
            <name>CCC</name>
			<module>BBB</module>
		</Area>
	</Sys>
	<Sys>
		<Area>
			<name>AAA</name>
	        <module>BBB</module>
		</Area>
	</Sys>
    </GC>
    "#;

    let foo: GC = serde_xml_rs::from_str(xml).unwrap();

    println!("{foo:#?}");
}

Rustexplorer.

1 Like

In the case i have

<GC version="x.x.x" endianness="little" db_path="xxx/yyy/zzz">
	<Sys>
		<Area>
			<name>AAA</name>
			<module>BBB</module>
		</Area>
	</Sys>
	<Sys>
		<Area>
			<name>AAA</name>
			<module>BBB</module>
		</Area>
	</Sys>
    <Stz>
         <Area>
			<name>AAA</name>
			<module>BBB</module>
	     </Area>
    </Stz>
</GC>

Is there a way to define different struct with Sys and Stz? appearently it defines the struct below in the same way

You can't combine both Stz and Sys tags in a struct but in an enum. This works for GC containting both Sys and Stz tags:

/*
[dependencies]
serde = { version = "1", features = ["derive"] }
serde-xml-rs = "*"
*/
#![allow(dead_code)]

use serde::Deserialize;
use serde_xml_rs;

#[derive(Debug, Deserialize)]
pub struct GC {
    version: String,
    endianness: String,
    db_path: String,
    #[serde(rename = "$value")]
    gc: Vec<GCContent>,
}

#[derive(Debug, Deserialize)]
enum GCContent {
    Sys(Sys),
    Stz(Stz),
}

#[derive(Debug, Deserialize)]
struct Sys {
    #[serde(rename = "$value")]
    sys: Vec<Area>,
}

#[derive(Debug, Deserialize)]
struct Stz {
    #[serde(rename = "$value")]
    stz: Vec<Area>,
}

#[derive(Debug, Deserialize)]
struct Area {
    name: Vec<Name>,
    module: Vec<Module>,
}

#[derive(Debug, Deserialize)]
struct Name {
    #[serde(rename = "$value")]
    value: String,
}

#[derive(Debug, Deserialize)]
struct Module {
    #[serde(rename = "$value")]
    value: String,
}

fn main() {
    let xml = r#"
<GC version="x.x.x" endianness="little" db_path="xxx/yyy/zzz">
	<Sys>
		<Area>
			<name>AAA</name>
			<module>BBB</module>
		</Area>
	</Sys>
	<Sys>
		<Area>
			<name>AAA</name>
			<module>BBB</module>
		</Area>
	</Sys>
    <Stz>
         <Area>
			<name>AAA</name>
			<module>BBB</module>
	     </Area>
    </Stz>
</GC>
    "#;

    let foo: GC = serde_xml_rs::from_str(xml).unwrap();

    println!("{foo:#?}");
}

Rustexplorer.