Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

writing with indent is not work #372

Closed
ImJeremyHe opened this issue Mar 15, 2022 · 4 comments
Closed

writing with indent is not work #372

ImJeremyHe opened this issue Mar 15, 2022 · 4 comments

Comments

@ImJeremyHe
Copy link

I wrote a function to prettify a one-line xml, but it failed.

use super::reader::Reader;
use super::writer::Writer;
use super::events::*;
fn to_tree(xml: &str) -> String {
    let mut reader = Reader::from_str(xml);
    let mut writer = Writer::new_with_indent(Vec::new(), 32, 4);
    loop {
        let mut buf = Vec::<u8>::new();
        match reader.read_event(&mut buf) {
            Ok(Event::Eof) => break,
            Ok(e) => {
                println!("{:?}", e);
                let _ = writer.write_event(e);
            },
            Err(_) => break,
        }
    }
    String::from_utf8(writer.into_inner()).unwrap()
}

I found that in the read_until_open function in reader, it returns Text event always. But the write_event function will always set

next_should_line_break = false;

I guess that's why it failed.
Maybe an empty text event should not be returned in the read_event function?

@dralley
Copy link
Collaborator

dralley commented Mar 15, 2022

@ImJeremyHe You can use Reader::trim_text for this. However, what it really does is trim all text events, including ones inside of elements, there's not a separate option for trimming only if a text element is "empty"

But if that's acceptable it does work

https://docs.rs/quick-xml/0.22.0/quick_xml/struct.Reader.html#method.trim_text

@ImJeremyHe
Copy link
Author

@dralley Thank you for your reply. I just realized that what leads to this problem is my setting trim_text true.
But I need to keep the white spaces in the text element. Maybe I should make a PR to fix this.

@Mingun
Copy link
Collaborator

Mingun commented Mar 31, 2022

Maybe an empty text event should not be returned in the read_event function?

Yeah, I've created #363 for this, but that is not simple change as I expected because of how buffer for store event content is handled. Events borrow from that buffer and its instance moved into generic function, so it is not possible just to add a loop here:

quick-xml/src/reader.rs

Lines 511 to 526 in d872771

fn read_event_buffered<'i, 'r, B>(&mut self, buf: B) -> Result<Event<'i>>
where
R: BufferedInput<'i, 'r, B>,
{
let event = match self.tag_state {
TagState::Opened => self.read_until_close(buf),
TagState::Closed => self.read_until_open(buf),
TagState::Empty => self.close_expanded_empty(),
TagState::Exit => return Ok(Event::Eof),
};
match event {
Err(_) | Ok(Event::Eof) => self.tag_state = TagState::Exit,
_ => {}
}
event
}

that would skip empty text events, because buffer moves at first iteration.

@Mingun
Copy link
Collaborator

Mingun commented Aug 10, 2022

Generating of empty events was fixed in #398; please comment here with additional info if it does not solve your case and I'll reopen

@Mingun Mingun closed this as completed Aug 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants