There is no such feature right now, but it's a good one to ask for so keep asking ! Again this would break round-trip so it's a lesser-of-evils problem. You could convert the output to a JSON *object* using json:transform-to-json-object() http://docs.marklogic.com/json:transform-to-json-object
then extract walk this object using map: operators and convert them to json using xdmp:to-json() As for Schema based transforms, thanks. I know of no other system that does this but it's a natural fit. I took the idea from previous published research I did a few years back. http://www.balisage.net/Proceedings/vol7/html/Lee01/BalisageVol7-Lee01.html JXON takes a lot more from the schema to influence the transformation then MarkLogic V6 does ... but the concept is similar. If we get enough people begging for this maybe it might make it into a future release. XML/JSON Transformations really are based on a "schema" transformation concept ... would be really nice if JSON Schema was non vaporware then one could say "take this XML Schema and this JSON schema and do some magic" ----------------------------------------------------------------------------- David Lee Lead Engineer MarkLogic Corporation [email protected] Phone: +1 812-482-5223 Cell: +1 812-630-7622 www.marklogic.com<http://www.marklogic.com/> From: [email protected] [mailto:[email protected]] On Behalf Of Stu Salsbury Sent: Sunday, April 21, 2013 10:52 AM To: MarkLogic Developer Discussion Subject: Re: [MarkLogic Dev General] transform-to-json -- custom config drops elements? One last thing and then I'll stop bugging you. You've already given me a bunch of time and I appreciate it. Is there a way to unwrap the root element in the JSON output(regardless of anything concerning arrays? Such that I could supply <someArbitraryContainingElementWhichDoesHaveASchema> <oneThingForJson id"1"/> <anotherThingForJson demo="true"/> </someArbitraryContainingElementWhichDoesHaveASchema> ...and get back... {"oneThingForJson": {"id":1,}, "anotherThingForJson": {"demo": true}} I'm looking for something, as you might guess, where I am not required to know anything about my document when calling the function. Either a parameter to request that format, or the ability to pass a sequence of nodes to the function resulting in such output would be handy. Since I didn't mention it before, I think schema-aware JSON transformations is a great feature! I'm working on a web service that will be substantially written in xquery fronted by a servlet, and had looked at java libraries to do it, but didn't find any that were schema-aware. I try to avoid coding to proprietary api's, but schema-aware JSON transformations is too good to pass up. So thank you for sucking me a little further into MarkLogic. :) On Sun, Apr 21, 2013 at 10:11 AM, Stu Salsbury <[email protected]<mailto:[email protected]>> wrote: Sorry, we cross-emailed. If the parent of the item with multiplicity has any attributes or other elements then the request to unwrap would be incompatible and would fall back to not unwrapping . In other words, the only schema for an element that would be compatible with this parameter is a complexType that has a single sequence with multiplicity. <xs:element name="foods"> <xs:complexType> <xs:sequence maxOccurs="unbounded" minOccurs="0"> <xs:element ref="food"/> </xs:sequence> </xs:complexType> </xs:element> I would submit that even though it would *only* be compatible with such a schema, that it is still worthwhile due to the "usefulness" or being able to group elements in XML in order to get arrays cleanly into json while maintaining decent semantics with pluralization of nouns. Without the feature, one needs to fudge the semantics of pluralization in either the XML or the JSON. But if this issue occurs at the top level of a node tree, then there is no longer a single root element. For example, I could start with the XML I have: <foods> <food/> <food/> </foods> and pre-transform it for purposes of JSON to <foods/> <foods/> ... which, of course, would need to have its own separate schema, all of which is work for the app developer. And we'd be left without a valid document since nothing contains the new foods elements. That this "feature" would be sort of a corner case is admittedly irksome, and yet the benefits seem large. Perhaps with the right parameter name, it would taste better: "unwrap-unitary-sequences" ?? :) On Sun, Apr 21, 2013 at 9:42 AM, Stu Salsbury <[email protected]<mailto:[email protected]>> wrote: Or maybe you meant: <foods > <food id="1" name="celery"> <location name="England"> <currency>pounds</currency> </location> </food> <food id="2" name="beets"> <location name="France"> <currency>francs</currency> </location> </food> <food id="3" name="goat cheese"> <location name="United States"> <currency>dollars</currency> </location> </food> </foods> which, with the appropriate schema, would hypothetically get me: {"foods":[{"id":1, "name":"celery", "location":{"name":"England", "currency":"pounds"}},{"id":2, "name":"beets", "location":{name:"France", "currency":"francs"}}, {"id":3, "name":"goat cheese", "location":{"name":"United States","currency":dollars"}}]} .. since you've already got the functionality of folding attributes and child elements together as subobjects of their parent. On Sun, Apr 21, 2013 at 9:23 AM, Stu Salsbury <[email protected]<mailto:[email protected]>> wrote: I'm not sure I follow. If I had food repeating, and food had a cost attribute and a location element (and I had appropriate schema, and the two hypothetical map parameters) I'd get: {"foods":[{"id":1, "name":"celery", "cost":50.2, "location": "Norway"},{"id":2, "name":"beets", "cost":23.3, "location":"Finland"},{"id":3, "name":"goat cheese", "cost":0.5, "location":"Denmark"}]} But wouldn't the example just be demonstrating what happens if I change the "price" element to a "cost" attribute and add a "location" element? I think I must be misunderstanding your question. On Sun, Apr 21, 2013 at 8:54 AM, David Lee <[email protected]<mailto:[email protected]>> wrote: Q: in your example what if foods had an attribute or more then one element name? ( say food repeating and cost attribute and location element) Sent from my iPad (excuse the terseness) David A Lee [email protected]<mailto:[email protected]> 812-630-7622<tel:812-630-7622> On Apr 21, 2013, at 10:50 AM, "Stu Salsbury" <[email protected]<mailto:[email protected]>> wrote: Thank you, David. Adding "element-namespace" certainly helps. I wish I'd thought of that. I guess that, unless the function is directly told that food is to be an array, it only renders the last element? Also, it would be great if: (a) there was a parameter to indicate that any elements which have multiplicity should be arrays; and (b) there was a parameter to indicate that the array elements should not be in the json (i.e. their content remains but is not wrapped with their name as a key/value). something like: (: I'm making up these parameter names -- this code isn't real!!! :) , $_ := map:put($c,"arrays-for-multiplicity",true); , $_ := map:put($c,"unwrap-array-elements",true); so that I'd get: {"foods":[{"id":1, "name":"celery", "price":50.2},{"id":2, "name":"beets", "price":23.3},{"id":3, "name":"goat cheese", "price":0.5}]} On Sun, Apr 21, 2013 at 4:49 AM, David Lee <[email protected]<mailto:[email protected]>> wrote: You need to indicate that food is an array element. Since you have now put food in a namespace your array-element-names isnt finding it. You either need to use an xs:QName() to give the full name of "food" or to declare the default namespace for the configuration using e.g. this should work , $_ := map:put($c,"array-element-names", xs:QName("agt:food") ) alternatively , $_ := map:put($c,"element-namespace","http://example.com/agt") which has the nice side effect of making the transformation reversable. ----------------------------------------------------------------------------- David Lee Lead Engineer MarkLogic Corporation [email protected]<mailto:[email protected]> Phone: +1 812-482-5224<tel:%2B1%20812-482-5224> Cell: +1 812-630-7622<tel:%2B1%20812-630-7622> www.marklogic.com<http://www.marklogic.com/> From: [email protected]<mailto:[email protected]> [mailto:[email protected]<mailto:[email protected]>] On Behalf Of Stu Salsbury Sent: Sunday, April 21, 2013 1:18 AM To: [email protected]<mailto:[email protected]> Subject: [MarkLogic Dev General] transform-to-json -- custom config drops elements? I have the following xml <foods xmlns="http://example.com/agt" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > <food id="1" name="celery"> <price>50.2</price> </food> <food id="2" name="beets"> <price>23.3</price> </food> <food id="3" name="goat cheese"> <price>0.5</price> </food> </foods> With the following xsd: <xs:schema targetNamespace="http://example.com/agt" attributeFormDefault="unqualified" elementFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" > <xs:element name="price" type="xs:decimal"/> <xs:element name="food"> <xs:complexType> <xs:sequence> <xs:element ref="price"/> </xs:sequence> <xs:attribute name="id" type="xs:integer"/> <xs:attribute name="name" type="xs:string"/> </xs:complexType> </xs:element> <xs:element name="foods"> <xs:complexType> <xs:sequence> <xs:element ref="food" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> When I execute the following query in the console: xquery version "1.0-ml"; import module namespace json = "http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy"; declare namespace agt = "http://example.com/agt"; let $c := json:config("custom") , $_ := map:put($c,"array-element-names", "food") return json:transform-to-json( doc("foods.xml") , $c ) ... I get: {"foods":{"food":{"id":3, "name":"goat cheese", "price":0.5}}} Something isn't clicking for me. What happened to the food elements? No array, and only the last one made it into the output. Note that taking out the array-element-names does *not* solve the missing food elements. Is this a bug or am I doing it wrong? I just started with MarkLogic Server, so I could very well be doing it wrong. Any advice appreciated. Regards, Stu _______________________________________________ General mailing list [email protected]<mailto:[email protected]> http://developer.marklogic.com/mailman/listinfo/general _______________________________________________ General mailing list [email protected]<mailto:[email protected]> http://developer.marklogic.com/mailman/listinfo/general _______________________________________________ General mailing list [email protected]<mailto:[email protected]> http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________ General mailing list [email protected] http://developer.marklogic.com/mailman/listinfo/general
