2012-05-24 9 views
8

Ich habe mehrere große DTD-Dateien. Ich habe trang verwendet, um sie in XSD-Dateien zu konvertieren, also könnte ich es leicht von JAXB und anderen Dienstprogrammen verwenden. Die generierte XSD-Datei hat jedoch alle Elemente auf der obersten Ebene deklariert. Dies bedeutet, dass jedes Element das Stammelement einer XML-Eingabe sein kann. Ich möchte nur ein bestimmtes Element angeben.Convert DTD zu XSD mit definierten Root (Start) Element

Diese mehreren Wurzelelemente verursachen einige Probleme, z.B. xjc generiert @XmlRootElement für alle Klassen, also muss ich zusätzliche Prüfungen hinzufügen.

Wie ich verstehe, ich brauche das generierte XSD neu zu schreiben, <xs:element> s <xs:complexType> s bewegen, element ref s in element type s verändert und so weiter, aber das ist zu viel Affe Arbeit sein würde, ohne die Möglichkeit, wenn alles getan, um zu überprüfen korrekt.

Gibt es einen effizienteren Weg, dies zu tun?

+0

+1 für eine Frage, die Sinn macht, aber lasst uns auch klarstellen, dass die Konvertierung von DTD zu XSD immer nur ungefähr ist. –

+0

@JirkaHanika Wie ich verstehe, approximiert die generierte XSD eine DTD sehr gut. Außer vielleicht DOCTYPE-Definitionen (keine Überraschung) und etwas Namespace-Zeug. Auch einige seltsame DTD-Konstrukte konnten nicht sauber in XSD umgewandelt werden. Das einzige Problem, mit dem ich momentan konfrontiert bin, ist, dass DTD den Begriff des Wurzelelements nicht definiert. (RelaxNG definiert es mit '', aber es wird schlecht unterstützt, 'xjc' ist damit fehlgeschlagen). – kan

+0

Ja, aber das Namensraum-Zeug ist ein großes Problem.Zusätzlich bedeuten viele Konstrukte, die ähnlich benannt sind, ziemlich unterschiedliche Dinge. +1 zur ersten Antwort, weil keine XSD-Semantik vorgetäuscht wird. –

Antwort

0

Ich habe einfache XSLT-Transformation verwendet, um das generierte XSD zu verarbeiten. Adaequat für meinen Fall:

<?xml version="1.0"?> 

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     > 
    <xsl:template match="@*|node()|comment()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()|comment()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="xs:element/@ref"/> 
    <xsl:template match="xs:element[@ref]"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:attribute name="type"><xsl:value-of select="@ref"/></xsl:attribute> 
      <xsl:attribute name="name"><xsl:value-of select="@ref"/></xsl:attribute> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="xs:element[@name = //xs:element/@ref and xs:complexType]"> 
     <xs:complexType name="{@name}"> 
      <xsl:apply-templates select="xs:complexType/node()"/> 
     </xs:complexType> 
    </xsl:template> 
    <xsl:template match="xs:element[@name = //xs:element/@ref and @type]"> 
     <xsl:choose> 
      <xsl:when test="//xs:complexType[@name = current()/@type]"> 
       <xs:complexType name="{@name}"> 
        <xs:complexContent> 
         <xs:extension base="{@type}"/> 
        </xs:complexContent> 
       </xs:complexType> 
      </xsl:when> 
      <xsl:otherwise> 
       <xs:simpleType name="{@name}"> 
        <xs:restriction base="{@type}"/> 
       </xs:simpleType> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

Es Elementdefinitionen verwiesen erkennt und sie comptexType s, Wechsel Refs. Alle nicht referenzierten Elemente werden zu Startelementen.

0

Von dem, was Sie beschreiben, und ignorieren die "Treue" der Konvertierung wie in einigen der Kommentare hingewiesen, ich habe nur mit der Tatsache, dass Sie nur auf der Suche nach einem automatischen Weg (was ich Anruf) XML Schema Refactoring. Ich bin verbunden mit QTAssistant, ein Produkt, das für diese Art von Arbeit gedacht ist, so ist, wie ich es tun würde ...

Eine Sache, die Sie von Hand tun müssen, egal was, ist herauszufinden und zu erfassen die Liste der Elemente, die Sie als root (oder nicht) sehen möchten ... und fertig: Drücken Sie eine Taste oder rufen Sie eine Befehlszeile auf, und Sie werden sicher wissen, ob eine gültige XSD generiert wird.

Eine Refactoring-Engine verwendet ein Besuchermuster, das in Ihrem Fall im Wesentlichen das tut, was Sie brauchen: erstellt globale Typen, entfernt unerwünschte globale Elementdefinitionen und ersetzt alle refedierten Elemente durch Inline-Deklarationen.

(Für jeden, der dies liest, der Substitutionsgruppen kennt, ersetzt dieses Refactoring keinen Verweis auf einen Kopf einer Substitutionsgruppe; da es sich um ein XSD von einer DTD handelt, ist dies hier kein Problem).

Diese Einfachheit und die Tatsache, dass sie wiederholbar und zuverlässig ist, wären die Hauptvorteile der Verwendung eines spezialisierten Refactoring-Tools; ein weiterer Vorteil: es kann auch XML-Namespaces zuweisen, wie auch immer Sie wollen ...

Wenn Sie an weiteren Details interessiert sind, lassen Sie es mich wissen und ich werde diesen Beitrag mit einem kleinen Beispiel und einigen Illustrationen aktualisieren.

Verwandte Themen