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]>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]>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]>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]>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]
>>>> 812-630-7622
>>>>
>>>>
>>>> On Apr 21, 2013, at 10:50 AM, "Stu Salsbury" <[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]>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]
>>>>> Phone: +1 812-482-5224****
>>>>>
>>>>> Cell: +1 812-630-7622
>>>>> www.marklogic.com
>>>>>
>>>>> ****
>>>>>
>>>>> ** **
>>>>>
>>>>> *From:* [email protected] [mailto:
>>>>> [email protected]] *On Behalf Of *Stu Salsbury
>>>>> *Sent:* Sunday, April 21, 2013 1:18 AM
>>>>> *To:* [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]
>>>>> http://developer.marklogic.com/mailman/listinfo/general
>>>>>
>>>>>
>>>> _______________________________________________
>>>> General mailing list
>>>> [email protected]
>>>> http://developer.marklogic.com/mailman/listinfo/general
>>>>
>>>>
>>>> _______________________________________________
>>>> General mailing list
>>>> [email protected]
>>>> http://developer.marklogic.com/mailman/listinfo/general
>>>>
>>>>
>>>
>>
>
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general