2016-04-18 7 views
3

Ich habe ein XML-Dokument und will es in einen JSON-String verwandeln:Trans atrribute in XML zu JSON

<?xml version="1.0" encoding="UTF-8"?> 
<root name="test-root"> 
<id lang="en">9876</id> 
<jobCode name="Teacher" xmlns:teacher="http://example.com/ns/teacher">1009</jobCode> 
</root> 

ich diese benutzerdefinierte Konfiguration verwenden, es zu tun:

let $config := json:config("custom")  
let $_ := map:put($config, "whitespace", "ignore") 
let $_ := map:put($config, "ignore-attribute-names",(xs:QName("name"),xs:QName("lang"))) 
return json:transform-to-json(fn:doc("/test1.xml"),$config) 

Unten ist die Ausgabe dieses Skripts:

{ 
    "root": { 
     "id": "9876", 
     "jobCode": "1009" 
    } 
} 

Es ist nicht das, was ich erwartet hatte, ich die aufnehmen möchten name Attribute in Elemente root aber ignorieren die Name Attribute in Elemente jobcode. Was ich erwartet habe, ist wie folgt:

{ 
    "root": { 
     "name": "test-root", 
     "id": "9876", 
     "jobCode": "1009" 
    } 
} 

Wie kann ich die Konfiguration anpassen, um diese Ausgabe zu bekommen? Vielen Dank!

Antwort

2

Ich glaube nicht, dass die Option so weit fortgeschritten ist, wie Sie hoffen.

In diesem Fall würde ich ein Stylesheet verwenden, um mein XML vorzureichen, um es ein bisschen mehr zu massieren. Hier ist eine Arbeitsprobe:

xquery version "1.0-ml"; 
import module namespace json="http://marklogic.com/xdmp/json" 
at "/MarkLogic/json/json.xqy"; 


let $xml := <root name="test-root"> 
<id lang="en">9876</id> 
<jobCode name="Teacher" xmlns:teacher="http://example.com/ns/teacher">1009</jobCode> 
</root> 

let $template := <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="@name[name(./..) = 'jobCode']" /> 

<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

let $filtered-xml := xdmp:xslt-eval($template, $xml) 

let $config := json:config("custom")  
let $_ := map:put($config, "whitespace", "ignore") 
let $_ := map:put($config, "ignore-attribute-names",(xs:QName("lang"))) 
return json:transform-to-json($filtered-xml,$config) 

Ergebnisse:

{ 
    "root": { 
    "name": "test-root", 
    "id": "9876", 
    "jobCode": "1009" 
    } 
} 

Und wenn Sie diesen Weg gehen, dann können Sie auch einfach auf den @lang Spiel wie auch in der Vorlage und entfernen Sie das ignorieren-Attribut Config alle zusammen.

+0

Das ist wirklich großartig! Vielen Dank!!! Durch die Kombination des styleSheet mit der JSON-API können wir eine komplexere benutzerdefinierte Transformation durchführen. –

+0

Ja, Sie können Ihren XML-Code auch direkt in die serialisierte Version des JSON-Transformationscodes umwandeln (suchen Sie im Installationsverzeichnis nach ./Config/json.xsd als Referenz). Das lässt der Fantasie nichts im Wege und Sie können genau die Ergebnisse erzielen, die Sie sich wünschen. Verstehen Sie auch, dass, wenn es ein xsd für Ihr XML gibt, der Transformator versuchen wird, sein Bestes zu geben, um damit zu beginnen (aber das hätte Ihre Herausforderung nicht adressiert). Wenn die ursprüngliche Antwort/Probe wirklich eine akzeptable Lösung für Sie ist, markieren Sie bitte die Antwort, um dies zu reflektieren. –

0

In Ihrem Original befinden sich beide Namensattribute im unbenannten Namespace. Elemente, aber keine Attribute erben den Namespace des aktuellen Bereichs. indem Sie angeben, dass alle Attribute ignoriert werden sollen QName ("name") Der Prozessor gibt alle "name" -Attribute korrekt aus. Ich verstehe, dass dies nicht das ist, was Sie wollten, aber bei Nachdenken sollte es das sein, was Sie erwarten ... dh wie ist der Code, um den Unterschied zwischen root/@ name und jobCode/@ name zu erkennen, wenn beide name-Attribute sind der gleiche QName?

Der Ansatz von David (Ennis) ist (einer der) empfohlenen Ansätze für diese Art von Problem. Der json: xxx-Code ist eine Convenience-Bibliothek, die gängige Anwendungsfälle einigermaßen gut und relativ einfach anspricht, aber als Kompromisslösung einfach jeden Anwendungsfall anspricht, wenn überhaupt.

Oft ist eine Kombination von vor-Transformation dann json: xxx Aufrufe ist nützlich, wenn Ihre Eingabe ist und "fast aber nicht ganz" ausgegeben ... Dann manchmal eine einfache Transformation von nur die Problemfälle gefolgt von der json: xxx-Bibliothek ist ein vernünftiger Kompromiss.

Insbesondere in ML 8.0 und höher das Ergebnis von json: transform-from-xml() erzeugt ein natives JSON-Objekt (keine Zeichenfolge). Abhängig von Ihrem Anwendungsfall kann dies ein signifikanter Unterschied sein - es muss nicht erneut geparst werden, um in natives JSON zu konvertieren. Auf der anderen Seite erfordert es Serialisierung, um in eine Zeichenfolge zu verwandeln.