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

Missing support for multiple yaml documents in a single file. #66

Closed
hemanik opened this issue Jan 15, 2018 · 10 comments
Closed

Missing support for multiple yaml documents in a single file. #66

hemanik opened this issue Jan 15, 2018 · 10 comments
Labels
yaml Issue related to YAML format backend

Comments

@hemanik
Copy link

hemanik commented Jan 15, 2018

yaml spec v1.2 contained information about files with multiple documents:
http://www.yaml.org/spec/1.2/spec.html

YAML uses three dashes (“---”) to separate directives from document content. This also serves to signal the start of a document if no directives are present. Three dots ( “...”) indicate the end of a document without starting a new one, for use in communication channels.

Example:

# Ranking of 1998 home runs
---
- Mark McGwire
- Sammy Sosa
- Ken Griffey

# Team ranking
---
- Chicago Cubs
- St Louis Cardinals

Example with ...:

---
time: 20:03:20
player: Sammy Sosa
action: strike (miss)
...
---
time: 20:03:47
player: Sammy Sosa
action: grand slam
...

The above-mentioned structures are not supported by object mapper at the moment.

@cowtowncoder
Copy link
Member

Does not work in what sense?

Note that since they are separate logical documents, you can not read into a single value, but you can construct a MappingIterator for reading them as a sequence of values. Or, at low level, can use a YAMLParser so that each document is separated by null token to signal end of a logical document (and last indicated by 2 nulls).

So perhaps this could be usage issue.

@zcourts
Copy link

zcourts commented Mar 22, 2018

For those not familiar with MappingIterator or how to use it here's an example

YAMLFactory yaml;
ObjectMapper mapper;

YAMLParser yamlParser = yaml.createParser("file-with-multiple-docs.yaml")
List<ObjectNode> docs =
mapper
      .readValues[ObjectNode](yamlParser, new TypeReference[ObjectNode] {})
      .readAll();

@cowtowncoder
Copy link
Member

@zcourts thank you for sharing this! Yes, that is the way (from Scala in this example?).

@teabot
Copy link

teabot commented Jun 17, 2019

How does this work for serialisation?

@cowtowncoder
Copy link
Member

@teabot You would use SequenceWriter, obtained via ObjectWriter, so you need to create ObjectWriter from mapper, then SequenceWriter with writeValues().

So something like

SequenceWriter sw = mapper.writer().writeValues(outputStream);

@piyushkumar13
Copy link

piyushkumar13 commented Nov 15, 2019

@cowtowncoder I am trying to serialize into multi docs, but not successful. Here is my code :

       File directory = new File("src/main/resources/output");
        String fileName = "output-multidocs.yaml";

        try(SequenceWriter sequenceWriter = mapper.writer().writeValues(new File(directory, fileName))){
            sequenceWriter.init(true);
            sequenceWriter.writeAll(detailsList); // detailsList is an arrayList of object. 
            sequenceWriter.writeAll(detailsList); // Expectation is this would create separate doc in the same yaml file. But it was appending to above list.

        }catch (Exception e){
            e.printStackTrace();
        }

@cowtowncoder
Copy link
Member

@piyushkumar13 Could you please file a new issue with title of something like "Can not write multi-document YAML output" or something, with that example, ref to this issue?

Btw, that init() should NOT be needed or used. I assume it does not make difference.

@piyushkumar13
Copy link

@cowtowncoder Sure. will raise a separate issue. Thanks for replying.

@blacelle
Copy link

In order to manage documents with Array at the root (instead of Object as the common case), we went with ContainerNode instead of ObjectNode:

JsonParser yamlParser = objectMapper.getFactory().createParser(input);
List<ContainerNode> docs = objectMapper.readValues(yamlParser, ContainerNode.class).readAll(); 

@cowtowncoder
Copy link
Member

Thank you @blacelle! I think nominal type JsonNode would also work and produce appropriate ArrayNode or ObjectNode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
yaml Issue related to YAML format backend
Projects
None yet
Development

No branches or pull requests

6 participants