Skip to content

xml5ever drops xml attributes with matching namespace and local names #538

@noahbald

Description

@noahbald

Hey there, I've run into this issue recently where only one attribute of a given namespace and local name will remain in the document. Consider the following test

#[test]
fn test_weird() -> anyhow::Result<()> {
    use rcdom::SerializableHandle;
    use xml5ever::{
        driver::{parse_document, XmlParseOpts},
        serialize::{serialize, SerializeOpts},
        tendril::TendrilSink,
    };

    let src = r##"<svg xmlns="http://www.w3.org/2000/svg" xmlns:x="http://www.w3.org/1999/xlink">
    <defs>
        <g id="mid-line"/>
        <g id="line-plus">
            <use href="#mid-line"/>
            <use href="#plus"/>
        </g>
        <g id="plus"/>
        <g id="line-circle">
            <use x:href="#mid-line"/>
        </g>
    </defs>
    <path d="M0 0" id="a"/>
    <use x:href="#a" x="50" y="50"/>
    <use x:href="#line-plus"/>
    <use x:href="#line-circle"/>
</svg>"##;
    println!("src:\n{src}");

    let dom: rcdom::RcDom =
        parse_document(rcdom::RcDom::default(), XmlParseOpts::default()).one(src);
    let mut sink: std::io::BufWriter<_> = std::io::BufWriter::new(Vec::new());
    serialize(
        &mut sink,
        &std::convert::Into::<SerializableHandle>::into(dom.document),
        SerializeOpts::default(),
    )?;

    let sink: Vec<_> = sink.into_inner()?;
    println!("\noutput:\n{}", String::from_utf8_lossy(&sink));
    Ok(())
}

The output for me is as follows

<svg xmlns="http://www.w3.org/2000/svg" xmlns:x="http://www.w3.org/1999/xlink">
    <defs>
        <g id="mid-line"/>
        <g id="line-plus">
            <use x:href="#mid-line"/>
            <use x:href="#plus"/>
        </g>
        <g id="plus"/>
        <g id="line-circle">
            <use x:href="#mid-line"/>
        </g>
    </defs>
    <path d="M0 0" id="a"/>
    <use x:href="#a" x="50" y="50"/>
    <use x:href="#line-plus"/>
    <use x:href="#line-circle"/>
</svg>

output:
<svg xmlns="http://www.w3.org/2000/svg">
    <defs>
        <g id="mid-line"></g>
        <g id="line-plus">
            <use x:href="#mid-line"></use>
            <use></use>
        </g>
        <g id="plus"></g>
        <g id="line-circle">
            <use></use>
        </g>
    </defs>
    <path d="M0 0" id="a"></path>
    <use x="50" y="50"></use>
    <use></use>
    <use></use>
</svg>

As you can see, all the x:href attributes, except for the first, seem to be dropped completely.
This doesn't seem like expected behaviour unless I'm missing something.

If needed, this are the versions I'm using

rcdom = { package = "markup5ever_rcdom", version = "0.3" }
xml5ever = "0.18.0"

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions