A pipeline system
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 20/100
Línea de trabajo
Start by reading the Reader, Writer, NsReader, and NamespaceResolver APIs in quick_xml; the issue identifies namespace resolution as the main implementation blocker. Then assess whether the proposed pipeline belongs in quick_xml and how it would support the listed XML processing use cases. Done means those design questions are resolved; the issue names no files or tests to run.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
I'm going to sketch out a pipeline/middleware system for quick_xml to explore whether there is any interest in taking this further. I started to build this but realized that it's difficult to implement without access to quick_xml internals, in particular the NamespaceResolver infrastructure. Pipelines are still possible without this infrastructure, but it requires writing to intermediate XML strings and parsing them again.
Here's what I envision:
Use cases
-
a
quick_xmlreader write canonicalized XML output. It'd like to layer that over a quick_xml Serde serializer without having to write to a string first. -
I want to take just an element and all its descendants in XML and post-process it (for instance applying canonicalization). I'd like to do that without having to serialize that to a separate XML string as an intermediate step.
-
quick_xmldeserializer isn't namespace aware. You can use prefixes in annotations in Rust types, but what if our input uses other prefixes? We could inject middleware that rewrites the prefixes to the set known by our types.
Traits
Reader trait
There's an abstract Reader trait. In reality we may need multiple ones to cover all the bases - a slice reader, a buffered reader, a slice ns reader, and a buffered ns reader.
The idea is that you can use this instead of a concrete reader.
I'm most interested in the most complex scenario, I have access to namespace prefixes and the like. In the rest of the story I will pretend there's only a single reader just for convenience (and it might a place to start anyway).
The ns reader trait should implement prefixes, and the various resolve_ methods.
Writer trait
Similarly, there's a Writer trait. This can be much simpler - it takes write_event. I think it also needs something to set up initialize known namespace prefixes (more about why later), and perhaps it's handy to be able to ask whether writing has already begun so we know whether to initialize or not.
Interesting implementations
(Ns)Reader
(Ns)Reader implements the Reader trait.
Writer
The Writer implements the Writer. This is so that our pipeline can end if we want XML output.
It may have a special feature to take the prefixes it gets and declares them on the outer element it writes if it doesn't already have such declarations. (or this may be in a little middleware).
Pipeline step
A pipeline step takes an Reader, a Writer (trait implementations) and pulls in stuff from the reader and writes to the writer. Very similar to what you'd do now from a concrete reader to a writer.
Buffer
A pipeline step may take a single event and ignore it, or split it into multiple events. We don't want complicated state management inside of pipeline steps; they should just deal with readers and writer. So we need something that implements both Reader and Writer. This buffers events in a deque.
When a pipeline pulls from a buffer, the buffered events will be returned first, until the buffer is empty. Then the buffer invokes its reader to put more events into its buffer.
It also manages namespaces separately using NamespaceResolver. Because pipeline steps could do interesting things to namespaces (this is in fact one of my use cases in canonicalization and prefix rewriting). A buffer can also be initialized with prefixes when writing starts, because a buffer may apply to a subset of the whole document.
Splitter
This splits a single stream into events into multiple streams of events, based on some criterion on BytesStart (and namespace info). All events until the end tag will be streamed to a specific pipeline. This way you can efficiently select one or more parts of the document for further processing.
This takes a hashmap of pipeline names to Writer implementations (a hashmap as how many pipelines should exist can in many cases only be determined at runtime) and a function that given a BytesStart and namespace information can determine which pipeline name it belongs to (or should not be piped through at all). By taking Writer implementation we can put in a Buffer with a pipeline step under it.
Namespace resolver
Right now NsReader already is a bit of a pipeline step on top of Reader. If we had a "namespace resolving" pipeline step we could generalize that. You could start a pipeline without namepaces, and add it as needed. I'm not entirely sure this is worth it, as I still think you need a reader trait that supports prefixes and resolve_ as you'd want to write your pipeline steps against those.
Related topics
This relates to #611 and #881 as those would enable pipeline support for Serde (de)serialization.
Next steps
We need to answer a bunch of questions:
-
Do want to support these use cases with
quick_xmlat all? -
Would it make sense to have this implemented in
quick_xmlor by another crate? -
If by another crate, can we make
quick_xmlopen up its APIs sufficiently to support this? The big blocker isNamespaceResolver, as without it, it becomes really difficult to implementBuffer.
- Lenguaje dominante
- Rust
- Estrellas
- 1.6k
- Forks
- 299
- Merge medio
- 2 d 4 h
- PR fusionados (30 d)
- 9
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de tafia/quick-xml
-
Parser accepts an empty element or attribute namePosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
DecodingReader::set_encoding panics when the XML declaration is longer than 64 bytesPosiblemente ocupada @emschwartz la tomó hace 4 días. Abiertobug encoding
Dificultad 4/5 3-5 días Aptitud para principiantes 30/100
tafia/quick-xml#1040 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
encoding optimization
Dificultad 4/5 3-5 días Aptitud para principiantes 55/100
tafia/quick-xml#1039 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
optimization question
Dificultad 4/5 3-5 días Aptitud para principiantes 52/100
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 4/5 1-2 días Aptitud para principiantes 53/100
tafia/quick-xml#1035 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de tafia/quick-xml
Issues similares
-
ライブラリを追加Abiertopriority middle
Dificultad 1/5 Menos de una hora Aptitud para principiantes 62/100
KATO-Hiro/AtCoderClans#13015 ·
Los mantenedores suelen responder en 1 día
-
needs-review
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
UCS-Care-Group/mailcraft#1429 ·
Los mantenedores suelen responder en 1 día
-
priority: medium ready
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
TusanHomichi/PSIV#646 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
area:tui bug P1
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
agent-of-empires/agent-of-empires#5705 · 1 comentario ·
Los mantenedores suelen responder en 1 día