Include YAML files from snakeyaml -
i have yaml files include, similar question, snakeyaml: how can include yaml file inside another?
for example:
%yaml 1.2 --- !include "load.yml" !include "load2.yml"
i having lot of trouble it. have constructor defined, , can make import 1 document, not two. error is:
exception in thread "main" expected '<document start>', found tag in 'reader', line 5, column 1: !include "load2.yml" ^
with 1 include, snakeyaml happy finds eof , processes import. two, it's not happy (above).
my java source is:
package yaml; import java.io.file; import java.io.fileinputstream; import java.io.filenotfoundexception; import java.io.inputstream; import org.yaml.snakeyaml.yaml; import org.yaml.snakeyaml.constructor.abstractconstruct; import org.yaml.snakeyaml.constructor.constructor; import org.yaml.snakeyaml.nodes.node; import org.yaml.snakeyaml.nodes.scalarnode; import org.yaml.snakeyaml.nodes.tag; public class main { final static constructor constructor = new myconstructor(); private static class importconstruct extends abstractconstruct { @override public object construct(node node) { if (!(node instanceof scalarnode)) { throw new illegalargumentexception("non-scalar !import: " + node.tostring()); } final scalarnode scalarnode = (scalarnode)node; final string value = scalarnode.getvalue(); file file = new file("src/imports/" + value); if (!file.exists()) { return null; } try { final inputstream input = new fileinputstream(new file("src/imports/" + value)); final yaml yaml = new yaml(constructor); return yaml.loadall(input); } catch (filenotfoundexception ex) { ex.printstacktrace(); } return null; } } private static class myconstructor extends constructor { public myconstructor() { yamlconstructors.put(new tag("!include"), new importconstruct()); } } public static void main(string[] args) { try { final inputstream input = new fileinputstream(new file("src/imports/example.yml")); final yaml yaml = new yaml(constructor); object object = yaml.load(input); system.out.println("loaded"); } catch (filenotfoundexception ex) { ex.printstacktrace(); } { } } }
question is, has done similar thing snakeyaml? thoughts might doing wrong?
i see 2 issues:
final inputstream input = new fileinputstream(new file("src/imports/" + value)); final yaml yaml = new yaml(constructor); return yaml.loadall(input);
you should using yaml.load(input)
, not yaml.loadall(input)
. loadall()
method returns multiple objects, construct()
method expects return single object.
the other issue may have inconsistent expectations way yaml processing pipeline works:
if think !include
works in c preprocessor sticks in contents of included file, way implement handle in presentation stage (parsing) or serialization stage (composing). have implemented in representation stage (constructing), !include
returns object, , structure of yaml file must consistent this.
let's have following files:
test1a.yaml
activity: "herding cats"
test1b.yaml
33
test1.yaml
favorites: !include test1a.yaml age: !include test1b.yaml
this work ok, , equivalent to
favorites: activity: "herding cats" age: 33
but following file not work:
!include test1a.yaml !include test1b.yaml
because there nothing how combine 2 values in larger hierarchy. you'd need this, if want array:
- !include test1a.yaml - !include test1b.yaml
or, again, handle custom logic in earlier stage such parsing or composing.
alternatively, need tell yaml library starting 2nd document (which error complaining about: expected '<document start>'
) since yaml supports multiple "documents" (top-level values) in single .yaml file.
Comments
Post a Comment