使用serde-xml-rs反序列化XML会创建Err(重复字段`$ value`)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用serde-xml-rs反序列化XML会创建Err(重复字段`$ value`)相关的知识,希望对你有一定的参考价值。

This是我试图解析的xml架构的一个例子。我只感兴趣的是几个领域。模式的根是PubmedArticleSet,其中包含> = 0个PubmedArticle条目。我对这些条目中包含的字段感兴趣。我在标题中收到错误,但我没有看到与错误here相关的问题。

<PubmedArticle>
  <MedlineCitation>
     <PMID>xxxxxxxx</PMID>
     <date tags i don't care about/>
     <other date tags i don't care about/>
     <Article>
       <tags I don't care about/>
         <children I don't care about>  
       <other tags I don't care about/>
         <children I don't care about>
       <AuthorList>
         <Author>
           <LastName>xxxx</LastName>
           <FirstName>i don't care about this</FirstName>
           <Initials>xx</Initials>
           <AffiliationInfo>
              <Affiliation>String of text</Affiliation>
           </AffiliationInfo>
          </Author>
          <Author>same as above</Author>
        </AuthorList>
        <Lots of stuff I don't care about/>
      </Article>
      <More stuff I don't care about/>
    </MedlineCitation>
    <Final stuff I don't care about/>
  </PubmedArticle>

我已经设置了以下结构:

#[derive(Serialize, Deserialize, Debug)]
struct PubmedArticleSet {
    #[serde(rename="$value")]
    pub articleset: Vec<PubmedArticle>
}

#[derive(Serialize, Deserialize, Debug)]
struct PubmedArticle {
    #[serde(rename="$value")]
    pub medlinecitation: MedlineCitation,
}

#[derive(Serialize, Deserialize, Debug)]
struct MedlineCitation {
    #[serde(rename="$value")]
    pub pmid: PMID,
    pub article: Article
}

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

#[derive(Serialize, Deserialize, Debug)]
struct Article {
    pub authorlist: AuthorList,
    pub publicationtypelist: Vec<PublicationType>
}

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

#[derive(Serialize, Deserialize, Debug)]
struct AuthorList {
    #[serde(rename="$value")]
    pub authorlist: Vec<Author>,
}

#[derive(Serialize, Deserialize, Debug)]
struct Author {
    #[serde(rename="$value")]
    pub author: (LastName, Initials),
    pub affiliation: Affiliation
}

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

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

#[derive(Serialize, Deserialize, Debug)]
struct Affiliation {
    #[serde(rename="$value")]
    pub affiliation: String

我尝试使用以下函数进行解析:

fn deser_article_records(result: &String) -> Result<PubmedArticleSet, Box<Error>> {
    if let Some(start) = result.find("<PubmedArticleSet>") {
        let records = serde_xml_rs::deserialize(result[start..].as_bytes())?;
        Ok(records)
    } else {
        Err("no articleset found")?
    }
}
答案

我的猜测是你有XML元素和其他东西。您没有在上面的代码段中显示示例,但是例如:

<Author ...>
<SomethingElse ...>
<Author>

serde_xml_rs似乎希望所有标记都与此评论相邻:https://github.com/RReverser/serde-xml-rs/issues/55

<Author...>
<Author...>
<SomethingElse ...>

如果您的XML不是这样,您可以使用Enum来解决这个问题。

EG

#[derive(Deserialize, Debug)]
struct Article {
    details: Vec<Detail>
}

#[derive(Deserialize, Debug)]
enum Detail {
    Author(Author),
    SomethingElse(SomethingElse)
}

#[derive(Debug, Deserialize)]
struct Author {
    ...
}

#[derive(Debug, Deserialize)]
struct SomethingElse {
    ...
}

以上是关于使用serde-xml-rs反序列化XML会创建Err(重复字段`$ value`)的主要内容,如果未能解决你的问题,请参考以下文章

反射真的慢么?动态代理会创建很多临时class?

如何将 XML 反序列化为 C# 中的对象? [复制]

在Gson反序列化期间使用Dagger进行依赖注入

如何反序列化xml文件的子节点

在.net中序列化读写xml方法的总结

C# XML 反序列化问题