Howto handle/load yaml files with anchors....

236 views
Skip to first unread message

DZeiss

unread,
Mar 11, 2010, 4:13:51 PM3/11/10
to SnakeYAML
Hello,

I have a yaml document http://de.oddb.org/resources/downloads/examples/de.oddb.yaml
which I want to read with snakeYAML.

My code is something like:

private DrugsProductLibrary dpL = new DrugsProductLibrary();
Constructor constructor = new Constructor(DrugsProduct.class);

TypeDescription drugsproductDescription = new
TypeDescription(DrugsProduct.class,ODDBVERSION
+"ODDB::Drugs::Product");
drugsproductDescription.setRoot(true);

TypeDescription businessCompanyDescription = new
TypeDescription(BusinessCompany.class,ODDBVERSION
+"ODDB::Business::Company");
....<continuing this for the whole datamodel>

constructor.addTypeDescription(drugsproductDescription);
constructor.addTypeDescription(businessCompanyDescription);
....<continuing this for the whole datamodel>

Loader loader = new Loader(constructor);
Yaml yaml = new Yaml(loader);
InputStream input = new FileInputStream(new File(fileName));

int counter=0;

for (Object data : yaml.loadAll(input)) {
dpL.addElement((DrugsProduct)data);
counter++;
}

There was another yaml testcase file which didnt have anchors and it
worked well. Now we have anchors, eg.
....
parts:
- &id002 !de.oddb.org,2007/ODDB::Drugs::Part
oid: 1724270
multi:
quantity:
size: 1
unit: &id001 !de.oddb.org,2007/ODDB::Drugs::Unit
oid: 19094
name: !de.oddb.org,2007/ODDB::Util::Multilingual
canonical:
:de: Durchstechflasche
synonyms: []

- &id003 !de.oddb.org,2007/ODDB::Drugs::Part
oid: 1727992
multi:
quantity:
size: 1
unit: *id001
....

parts:
- *id002
...

And I get the errormessage at runtime:

Can't construct a java object for tag:yaml.org,
2002:....medication.model.DrugsPackage@3901c6; No constructors with 1
arguments found for class xxx.yyyyyyy.medication.model.DrugsPart
in "<reader>", line 1, column 5:
--- !de.oddb.org,2007/ODDB::Drugs::P ...
^

I think it fails because it is using the *id002 and doesnt use the
object instead.
Is this hypothesis correct?
How do I read this yaml file then?

Thanks in advance

DZeiss


Andrey

unread,
Mar 11, 2010, 6:19:23 PM3/11/10
to SnakeYAML
When I look at the error message I see the problem in the first line:

>in "<reader>", line 1, column 5:

But the error is about DrugsPart while the first line in the YAML
document (http://de.oddb.org/resources/downloads/examples/
de.oddb.yaml) is about Product.

I am afraid there is some inconsistency in the report. Can you may be
provide a test case with no external dependancies to reproduce the
error ?

BTW, is the YAML documented generated by Perl ?

-
Andrey

On Mar 11, 10:13 pm, DZeiss <dze...@googlemail.com> wrote:
> Hello,
>

> I have a yaml documenthttp://de.oddb.org/resources/downloads/examples/de.oddb.yaml

DZeiss

unread,
Mar 12, 2010, 1:13:01 AM3/12/10
to SnakeYAML
Hello

Thanks for the answer!

> BTW, is the YAML documented generated by Perl ?

Sorry, I dont have that information since it is an external database
which I am trying to read.
But since the ojects are all called "Drugs::<something>", the two :
make it look like Perl to me.

> When I look at the error message I see the problem in the first line:
>
> >in "<reader>", line 1, column 5:
>
> But the error is about DrugsPart while the first line in the YAML
> document (http://de.oddb.org/resources/downloads/examples/
> de.oddb.yaml) is about Product.

Well, the datamodel are 17 POJOs, so I didnt post them all here.

DrugsProduct is the root and from this object all other objects are
somehow connected through lists...., thats why the errormessage tells
you line 1 but it is actually far way down. It also did cost me some
time to realise this.

> I am afraid there is some inconsistency in the report. Can you may be
> provide a test case with no external dependancies to reproduce the
> error ?

My main problem is the errormessage

"No constructors with 1 arguments found for class"

It fails to read

parts:
- *id002

because it excpects a whole object there like

parts:
- &id002 !de.oddb.org,2007/ODDB::Drugs::Part
oid: 1724270
multi:
quantity:
size: 1
unit: &id001 !de.oddb.org,2007/ODDB::Drugs::Unit
oid: 19094
name: !de.oddb.org,2007/ODDB::Util::Multilingual
canonical:
:de: Durchstechflasche
synonyms: []

So the anchor & and * are not really working in my program. How can I
fix this?

Thanks

DZeiss

Andrey

unread,
Mar 12, 2010, 6:38:16 PM3/12/10
to SnakeYAML
I asked about Perl because it often generates invalid YAML.

There is no problem with anchors and aliases in SnakeYAML. The problem
is somewhere else.

The error message you see is normally reported for a scalar with a
custom tag. SnakeYAML tries to invoke a single argument constructor
passing the scalar value.
You can try to reduce the YAML document until you find a simple
document which fails. If you can provide a JUnit test which fails it
would greatly simplify finding the error.
If you see SnakeYAML does work properly feel free to create an issue.

-
Andrey

Andrey

unread,
Mar 15, 2010, 5:33:42 AM3/15/10
to SnakeYAML
The document is Ok. Check your code. I have written a small test. It
creates a map for each "!de.oddb.org,2007/ODDB" tag.
(instead of JavaBean)
This is how it looks like. Unfortunately I had to modify the code to
make ConstructYamlMap public.


package org.yaml.snakeyaml;

import junit.framework.TestCase;

import org.yaml.snakeyaml.constructor.SafeConstructor;

public class Y1 extends TestCase {

public void test1() {
Yaml yaml = new Yaml(new Loader(new CustomConstructor()));
String input = Util.getLocalResource("yaml1.txt");
for (Object obj : yaml.loadAll(input)) {
System.out.println(obj);
}
}

private class CustomConstructor extends SafeConstructor {
public CustomConstructor() {
// define tags which begin with !de.oddb.org,2007/ODDB
String prefix = "!de.oddb.org,2007/ODDB";
this.yamlMultiConstructors.put(prefix, new
ConstructYamlMap());
}
}
}

Andrey

unread,
Mar 16, 2010, 10:22:25 AM3/16/10
to SnakeYAML
You can check an example here:
http://code.google.com/p/snakeyaml/source/browse/src/test/java/org/yaml/snakeyaml/issues/issue56/PerlTest.java

It is using the reduced YAML you have provided.

I have also made some modification in the code:
http://code.google.com/p/snakeyaml/issues/detail?id=56

Reply all
Reply to author
Forward
0 new messages