2012-04-11 6 views
0

Ich versuche herauszufinden, wie ein erweitertes ("Erweiterung") XML-Schema-Element in die Form des ursprünglichen Elements umgewandelt werden kann. Das Beispielszenario ist die folgende:Umwandlung von einem XML-Schematyp in einen anderen mit XQuery

<?xml version="1.0" encoding="UTF-8"?> 
<schema targetNamespace="http://www.example.com/address" 
     xmlns="http://www.w3.org/2001/XMLSchema" 
     xmlns:add="http://www.example.com/address" 
     elementFormDefault="qualified"> 

<complexType name="Address"> 
    <sequence> 
    <element name="name" type="string"/> 
    <element name="street" type="string"/> 
    <element name="city" type="string"/> 
    </sequence> 
</complexType> 

<complexType name="UKAddress"> 
    <complexContent> 
    <extension base="add:Address"> 
     <sequence> 
     <element name="postcode" type="ipo:UKPostcode"/> 
     </sequence> 
     <attribute name="exportCode" type="positiveInteger" fixed="1"/> 
    </extension> 
    </complexContent> 
</complexType> 

<simpleType name="UKPostcode"> 
    <restriction base="string"> 
     <pattern value="[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][A-Z]{2}"/> 
    </restriction> 
</simpleType> 

<element name="UKAddress" type="add:UKAddress" /> 
<element name="Address" type="add:Address" /> 
</schema> 

Dies ist das Schema ist, und ich versuche, dies zu transfrom:

<UKAddress xmlns="http://www.example.com/address" exportCode="1"> 
    <name>Address1</name> 
    <street>Example street</street> 
    <city>London</city> 
    <postcode>AA00 0AA</postcode> 
</UKAddress> 

In diese:

<UKAddress xmlns="http://www.example.com/address"> 
    <name>Address1</name> 
    <street>Example street</street> 
    <city>London</city> 
</UKAddress> 

mit Nicht alle Kinder verwandeln Element eins nach dem anderen (das funktioniert gut), aber mit einem generischen Weg, wie Cast. Der Hauptpunkt besteht darin, die inherit-ähnliche Struktur der Address-Elemente irgendwie zu verwenden und das hohe Paar zwischen map (Xquery) und leaf-Elementen zu vermeiden. Ich habe versucht, einige Cast-Funktion zu finden, aber das sind für primitive, ich habe versucht, xsi: type und ich habe versucht, alle Kinder-Element zu fragen, und sie zu filtern. Ich habe keinen funktionierenden Weg gefunden. Hat sich jemand damit getroffen? Vielen Dank!

Antwort

0

Gestern hatte ich einige Runden mit der Antwort. Zuerst habe ich versucht, eine XPath-Abfrage zu machen, die die untergeordneten Elemente mir filtert, wie folgt aus:

declare function xf:testAddress($uKAddress1 as element()) 
    as element() { 
     let $UKAddress := $uKAddress1 
     return 
      <ns0:Address> 
       {$UKAddress/*[local-name()=('name', 'street', 'city')]} 
      <ns0:Address> 
}; 

(local-name ist wichtig: einfacher Name() den Namespace enthalten, oder schlimmsten: eine Dummy Namespace, wenn die Engine solche Dinge verwendet) Das Problem ist, dass die rechte Seite des Ausdrucks nicht dynamisch ist und das XQuery das Schema natürlich nicht ohne Hilfe sehen kann. Eine Möglichkeit, dies ist das folgende Skript zu lösen:

http://en.wikibooks.org/wiki/XQuery/XML_Schema_to_Instance

Damit konnte ich eine Dummy-Instanz der Adresse machen, und dann konnte ich diese Instanz verwenden, um die Kinder zu kartieren. Es ist also eine Art Lösung, aber ich denke, es ist nicht der richtige Weg, und dies bringt bei jeder Anfrage viel zusätzliche Arbeit mit sich.

Verwandte Themen