Jackson YAML: support for anchors and references











up vote
6
down vote

favorite
1












I'm investigating the use of YAML for a somewhat complicated metadata language. It would help to make the documents smaller and less complex if we could use YAML's anchors and references. I've written some test code that seems to show that Jackson's YAML implementation doesn't support this feature (and/or doesn't surface SnakeYAML's support for this feature).



Here is my test YAML file:



set_one:
bass: tama rockstar 22x16
snare: &ludwig ludwig supralight 6.5x15
tom1: tama rockstar 12x11
tom2: tama rockstar 16x16

set_two:
snare: *ludwig


I'm parsing this file like so:



    ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
FileInputStream fis = null;

try
{
fis = new FileInputStream(file);
JsonNode nodeTree = mapper.readTree(fis);
examineObject(nodeTree, 0);
}
...


Here is the out from my "examineObject()" method (you can probably guess what it does):



key = "set_one", type = OBJECT
key = "bass", type = STRING, value = "tama rockstar 22x16"
key = "snare", type = STRING, value = "ludwig supralight 6.5x15"
key = "tom1", type = STRING, value = "tama rockstar 12x11"
key = "tom2", type = STRING, value = "tama rockstar 16x16"
key = "set_two", type = OBJECT
key = "snare", type = STRING, value = "ludwig"


Clearly something knew enough to omit the anchor value from "set_one.snare" but, in the debugger, I can't find that value anywhere in the JsonNode for this element. The real problem is that the value of "set_two.snare" is just "ludwig". The reference symbol ('*') has been stripped, but the value is that of the reference and not the element it is referring to.



I'm using Jackson version 2.8.3 and SnakeYaml version 1.17. I am constrained to using Jackson as this is only part of a much bigger project which already uses Jackson for JSON.



What I would really like is if Jackson could automatically resolve references and make a copy of the referenced value. In my example this would mean that the value of "set_two.snare" would be "ludwig supralight 6.5x15".



If I can't get my first choice then I would like Jackson to preserve both the anchors and the references so that I could manually post-process the node tree and resolve the references myself. For example, when I saw that the value of "set_two.snare" was "*ludwig", I could search the tree for a node with an anchor of "&ludwig" and make a copy of that node.



If there is an answer, I have the feeling that it will probably involve the "com.fasterxml.jackson.dataformat.yaml.YAMLParser.Feature" class somehow. Unfortunately I can't find any documentation on the features (if they exist) that will enable the behavior I am looking for.










share|improve this question




























    up vote
    6
    down vote

    favorite
    1












    I'm investigating the use of YAML for a somewhat complicated metadata language. It would help to make the documents smaller and less complex if we could use YAML's anchors and references. I've written some test code that seems to show that Jackson's YAML implementation doesn't support this feature (and/or doesn't surface SnakeYAML's support for this feature).



    Here is my test YAML file:



    set_one:
    bass: tama rockstar 22x16
    snare: &ludwig ludwig supralight 6.5x15
    tom1: tama rockstar 12x11
    tom2: tama rockstar 16x16

    set_two:
    snare: *ludwig


    I'm parsing this file like so:



        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
    FileInputStream fis = null;

    try
    {
    fis = new FileInputStream(file);
    JsonNode nodeTree = mapper.readTree(fis);
    examineObject(nodeTree, 0);
    }
    ...


    Here is the out from my "examineObject()" method (you can probably guess what it does):



    key = "set_one", type = OBJECT
    key = "bass", type = STRING, value = "tama rockstar 22x16"
    key = "snare", type = STRING, value = "ludwig supralight 6.5x15"
    key = "tom1", type = STRING, value = "tama rockstar 12x11"
    key = "tom2", type = STRING, value = "tama rockstar 16x16"
    key = "set_two", type = OBJECT
    key = "snare", type = STRING, value = "ludwig"


    Clearly something knew enough to omit the anchor value from "set_one.snare" but, in the debugger, I can't find that value anywhere in the JsonNode for this element. The real problem is that the value of "set_two.snare" is just "ludwig". The reference symbol ('*') has been stripped, but the value is that of the reference and not the element it is referring to.



    I'm using Jackson version 2.8.3 and SnakeYaml version 1.17. I am constrained to using Jackson as this is only part of a much bigger project which already uses Jackson for JSON.



    What I would really like is if Jackson could automatically resolve references and make a copy of the referenced value. In my example this would mean that the value of "set_two.snare" would be "ludwig supralight 6.5x15".



    If I can't get my first choice then I would like Jackson to preserve both the anchors and the references so that I could manually post-process the node tree and resolve the references myself. For example, when I saw that the value of "set_two.snare" was "*ludwig", I could search the tree for a node with an anchor of "&ludwig" and make a copy of that node.



    If there is an answer, I have the feeling that it will probably involve the "com.fasterxml.jackson.dataformat.yaml.YAMLParser.Feature" class somehow. Unfortunately I can't find any documentation on the features (if they exist) that will enable the behavior I am looking for.










    share|improve this question


























      up vote
      6
      down vote

      favorite
      1









      up vote
      6
      down vote

      favorite
      1






      1





      I'm investigating the use of YAML for a somewhat complicated metadata language. It would help to make the documents smaller and less complex if we could use YAML's anchors and references. I've written some test code that seems to show that Jackson's YAML implementation doesn't support this feature (and/or doesn't surface SnakeYAML's support for this feature).



      Here is my test YAML file:



      set_one:
      bass: tama rockstar 22x16
      snare: &ludwig ludwig supralight 6.5x15
      tom1: tama rockstar 12x11
      tom2: tama rockstar 16x16

      set_two:
      snare: *ludwig


      I'm parsing this file like so:



          ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
      FileInputStream fis = null;

      try
      {
      fis = new FileInputStream(file);
      JsonNode nodeTree = mapper.readTree(fis);
      examineObject(nodeTree, 0);
      }
      ...


      Here is the out from my "examineObject()" method (you can probably guess what it does):



      key = "set_one", type = OBJECT
      key = "bass", type = STRING, value = "tama rockstar 22x16"
      key = "snare", type = STRING, value = "ludwig supralight 6.5x15"
      key = "tom1", type = STRING, value = "tama rockstar 12x11"
      key = "tom2", type = STRING, value = "tama rockstar 16x16"
      key = "set_two", type = OBJECT
      key = "snare", type = STRING, value = "ludwig"


      Clearly something knew enough to omit the anchor value from "set_one.snare" but, in the debugger, I can't find that value anywhere in the JsonNode for this element. The real problem is that the value of "set_two.snare" is just "ludwig". The reference symbol ('*') has been stripped, but the value is that of the reference and not the element it is referring to.



      I'm using Jackson version 2.8.3 and SnakeYaml version 1.17. I am constrained to using Jackson as this is only part of a much bigger project which already uses Jackson for JSON.



      What I would really like is if Jackson could automatically resolve references and make a copy of the referenced value. In my example this would mean that the value of "set_two.snare" would be "ludwig supralight 6.5x15".



      If I can't get my first choice then I would like Jackson to preserve both the anchors and the references so that I could manually post-process the node tree and resolve the references myself. For example, when I saw that the value of "set_two.snare" was "*ludwig", I could search the tree for a node with an anchor of "&ludwig" and make a copy of that node.



      If there is an answer, I have the feeling that it will probably involve the "com.fasterxml.jackson.dataformat.yaml.YAMLParser.Feature" class somehow. Unfortunately I can't find any documentation on the features (if they exist) that will enable the behavior I am looking for.










      share|improve this question















      I'm investigating the use of YAML for a somewhat complicated metadata language. It would help to make the documents smaller and less complex if we could use YAML's anchors and references. I've written some test code that seems to show that Jackson's YAML implementation doesn't support this feature (and/or doesn't surface SnakeYAML's support for this feature).



      Here is my test YAML file:



      set_one:
      bass: tama rockstar 22x16
      snare: &ludwig ludwig supralight 6.5x15
      tom1: tama rockstar 12x11
      tom2: tama rockstar 16x16

      set_two:
      snare: *ludwig


      I'm parsing this file like so:



          ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
      FileInputStream fis = null;

      try
      {
      fis = new FileInputStream(file);
      JsonNode nodeTree = mapper.readTree(fis);
      examineObject(nodeTree, 0);
      }
      ...


      Here is the out from my "examineObject()" method (you can probably guess what it does):



      key = "set_one", type = OBJECT
      key = "bass", type = STRING, value = "tama rockstar 22x16"
      key = "snare", type = STRING, value = "ludwig supralight 6.5x15"
      key = "tom1", type = STRING, value = "tama rockstar 12x11"
      key = "tom2", type = STRING, value = "tama rockstar 16x16"
      key = "set_two", type = OBJECT
      key = "snare", type = STRING, value = "ludwig"


      Clearly something knew enough to omit the anchor value from "set_one.snare" but, in the debugger, I can't find that value anywhere in the JsonNode for this element. The real problem is that the value of "set_two.snare" is just "ludwig". The reference symbol ('*') has been stripped, but the value is that of the reference and not the element it is referring to.



      I'm using Jackson version 2.8.3 and SnakeYaml version 1.17. I am constrained to using Jackson as this is only part of a much bigger project which already uses Jackson for JSON.



      What I would really like is if Jackson could automatically resolve references and make a copy of the referenced value. In my example this would mean that the value of "set_two.snare" would be "ludwig supralight 6.5x15".



      If I can't get my first choice then I would like Jackson to preserve both the anchors and the references so that I could manually post-process the node tree and resolve the references myself. For example, when I saw that the value of "set_two.snare" was "*ludwig", I could search the tree for a node with an anchor of "&ludwig" and make a copy of that node.



      If there is an answer, I have the feeling that it will probably involve the "com.fasterxml.jackson.dataformat.yaml.YAMLParser.Feature" class somehow. Unfortunately I can't find any documentation on the features (if they exist) that will enable the behavior I am looking for.







      jackson yaml






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Oct 16 '16 at 20:27

























      asked Oct 16 '16 at 19:45









      gilbertpilz

      902925




      902925
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          1
          down vote













          I just tried to make anchors/aliases work in Jackson... and failed.
          You can see here that alias based id support is not implemented. The _currentAnchor instance variable is set and exposed by getObjectId(), but I didn't find a practical way to hook into Jackson to use that method. This is not my first fight with Jacksons Object-Id resolution architecture. Be advised not the spend too much time with it.



          My solution was using the snakeyaml library directly.






          share|improve this answer




























            up vote
            0
            down vote













            First, Jackson actually does support YAML anchors and references, at least to degree they work with how Jackson supports Object Id references with @JsonIdentityInfo: limitation being that you can not -- for example -- refer to one key/value pair of am Object.



            But identity id/reference handling is only enabled for types and properties specified by annotating then with @JsonIdentityInfo.
            So you have to annotate either types that may be referenced, or properties (no need to do both).



            One thing that may help here is to consider that Object Id handling by Jackson is very similar for all formats: so although jackson-dataformat-yaml does expose "native" Object (and Type) Ids that YAML has (and JSON does not have), handling at databinding level is identical. So if you can make Object Id/References work with JSON (which adds extra id property), it will work with YAML as well.



            There is one extra thing that is related: YAMLParser.Feature.USE_NATIVE_OBJECT_ID which determines how references and ids are expressed when writing YAML -- by default, it uses native anchors, but it can be turned off to use "JSON-like" plain properties.



            I hope this helps. For additional help the best place would be jackson-users mailing list.






            share|improve this answer





















              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f40074700%2fjackson-yaml-support-for-anchors-and-references%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              1
              down vote













              I just tried to make anchors/aliases work in Jackson... and failed.
              You can see here that alias based id support is not implemented. The _currentAnchor instance variable is set and exposed by getObjectId(), but I didn't find a practical way to hook into Jackson to use that method. This is not my first fight with Jacksons Object-Id resolution architecture. Be advised not the spend too much time with it.



              My solution was using the snakeyaml library directly.






              share|improve this answer

























                up vote
                1
                down vote













                I just tried to make anchors/aliases work in Jackson... and failed.
                You can see here that alias based id support is not implemented. The _currentAnchor instance variable is set and exposed by getObjectId(), but I didn't find a practical way to hook into Jackson to use that method. This is not my first fight with Jacksons Object-Id resolution architecture. Be advised not the spend too much time with it.



                My solution was using the snakeyaml library directly.






                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  I just tried to make anchors/aliases work in Jackson... and failed.
                  You can see here that alias based id support is not implemented. The _currentAnchor instance variable is set and exposed by getObjectId(), but I didn't find a practical way to hook into Jackson to use that method. This is not my first fight with Jacksons Object-Id resolution architecture. Be advised not the spend too much time with it.



                  My solution was using the snakeyaml library directly.






                  share|improve this answer












                  I just tried to make anchors/aliases work in Jackson... and failed.
                  You can see here that alias based id support is not implemented. The _currentAnchor instance variable is set and exposed by getObjectId(), but I didn't find a practical way to hook into Jackson to use that method. This is not my first fight with Jacksons Object-Id resolution architecture. Be advised not the spend too much time with it.



                  My solution was using the snakeyaml library directly.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 8 at 9:21









                  André B.

                  16016




                  16016
























                      up vote
                      0
                      down vote













                      First, Jackson actually does support YAML anchors and references, at least to degree they work with how Jackson supports Object Id references with @JsonIdentityInfo: limitation being that you can not -- for example -- refer to one key/value pair of am Object.



                      But identity id/reference handling is only enabled for types and properties specified by annotating then with @JsonIdentityInfo.
                      So you have to annotate either types that may be referenced, or properties (no need to do both).



                      One thing that may help here is to consider that Object Id handling by Jackson is very similar for all formats: so although jackson-dataformat-yaml does expose "native" Object (and Type) Ids that YAML has (and JSON does not have), handling at databinding level is identical. So if you can make Object Id/References work with JSON (which adds extra id property), it will work with YAML as well.



                      There is one extra thing that is related: YAMLParser.Feature.USE_NATIVE_OBJECT_ID which determines how references and ids are expressed when writing YAML -- by default, it uses native anchors, but it can be turned off to use "JSON-like" plain properties.



                      I hope this helps. For additional help the best place would be jackson-users mailing list.






                      share|improve this answer

























                        up vote
                        0
                        down vote













                        First, Jackson actually does support YAML anchors and references, at least to degree they work with how Jackson supports Object Id references with @JsonIdentityInfo: limitation being that you can not -- for example -- refer to one key/value pair of am Object.



                        But identity id/reference handling is only enabled for types and properties specified by annotating then with @JsonIdentityInfo.
                        So you have to annotate either types that may be referenced, or properties (no need to do both).



                        One thing that may help here is to consider that Object Id handling by Jackson is very similar for all formats: so although jackson-dataformat-yaml does expose "native" Object (and Type) Ids that YAML has (and JSON does not have), handling at databinding level is identical. So if you can make Object Id/References work with JSON (which adds extra id property), it will work with YAML as well.



                        There is one extra thing that is related: YAMLParser.Feature.USE_NATIVE_OBJECT_ID which determines how references and ids are expressed when writing YAML -- by default, it uses native anchors, but it can be turned off to use "JSON-like" plain properties.



                        I hope this helps. For additional help the best place would be jackson-users mailing list.






                        share|improve this answer























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          First, Jackson actually does support YAML anchors and references, at least to degree they work with how Jackson supports Object Id references with @JsonIdentityInfo: limitation being that you can not -- for example -- refer to one key/value pair of am Object.



                          But identity id/reference handling is only enabled for types and properties specified by annotating then with @JsonIdentityInfo.
                          So you have to annotate either types that may be referenced, or properties (no need to do both).



                          One thing that may help here is to consider that Object Id handling by Jackson is very similar for all formats: so although jackson-dataformat-yaml does expose "native" Object (and Type) Ids that YAML has (and JSON does not have), handling at databinding level is identical. So if you can make Object Id/References work with JSON (which adds extra id property), it will work with YAML as well.



                          There is one extra thing that is related: YAMLParser.Feature.USE_NATIVE_OBJECT_ID which determines how references and ids are expressed when writing YAML -- by default, it uses native anchors, but it can be turned off to use "JSON-like" plain properties.



                          I hope this helps. For additional help the best place would be jackson-users mailing list.






                          share|improve this answer












                          First, Jackson actually does support YAML anchors and references, at least to degree they work with how Jackson supports Object Id references with @JsonIdentityInfo: limitation being that you can not -- for example -- refer to one key/value pair of am Object.



                          But identity id/reference handling is only enabled for types and properties specified by annotating then with @JsonIdentityInfo.
                          So you have to annotate either types that may be referenced, or properties (no need to do both).



                          One thing that may help here is to consider that Object Id handling by Jackson is very similar for all formats: so although jackson-dataformat-yaml does expose "native" Object (and Type) Ids that YAML has (and JSON does not have), handling at databinding level is identical. So if you can make Object Id/References work with JSON (which adds extra id property), it will work with YAML as well.



                          There is one extra thing that is related: YAMLParser.Feature.USE_NATIVE_OBJECT_ID which determines how references and ids are expressed when writing YAML -- by default, it uses native anchors, but it can be turned off to use "JSON-like" plain properties.



                          I hope this helps. For additional help the best place would be jackson-users mailing list.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Oct 18 '16 at 18:22









                          StaxMan

                          80.5k24158199




                          80.5k24158199






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f40074700%2fjackson-yaml-support-for-anchors-and-references%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              這個網誌中的熱門文章

                              Xamarin.form Move up view when keyboard appear

                              Post-Redirect-Get with Spring WebFlux and Thymeleaf

                              Anylogic : not able to use stopDelay()