Announcement

Collapse
No announcement yet.

XML zu XML per XSLT

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • XML zu XML per XSLT

    Hi,

    meine Ausgangsstruktur sieh folgendermaßen aus.

    <XML>
    <MODELS>
    <MODEL>
    <AttributesBig>
    <Instance>
    <Attributes>
    <Connection>

    Diese will ich folgende Struktur umwandeln (xmi 1.3 UML 1.4)



    <XMI.content>
    <UML:Model>
    <UML:Namespace.ownedElement>
    <UML:Package>
    <UML:Namespace.ownedElement>
    <UML:Model >
    <UML:Namespace.ownedElement>
    <UML:Actor>
    </UML:Actor>
    <UML:UseCase>
    </UML:UseCase>
    <UML:Comment>
    <UML:ModelElement.name>
    </UML:ModelElement.name>
    <UML:Comment.body>
    </UML:Comment.body>
    <UML:Comment.annotatedElement>
    </UML:Comment.annotatedElement>
    </UML:Comment>


    <UML:Association xmi.id = 'B'
    name = '{Test}' visibility = 'package' isSpecification = 'false'
    isAbstract = 'false' stereotype = 'XX.11'>
    <UML:Association.connection>
    <UML:AssociationEnd xmi.id = 'C' visibility = 'public' isSpecification = 'false'
    isNavigable = 'false' aggregation = 'none'
    targetScope = 'instance' changeability = 'changeable'>
    <UML:AssociationEnd.multiplicity>
    <UML:Multiplicity/>
    </UML:AssociationEnd.multiplicity>
    <UML:AssociationEnd.participant>
    <UML:Classifier xmi.idref = 'D'/>
    </UML:AssociationEnd.participant>
    </UML:AssociationEnd>
    <UML:AssociationEnd xmi.id = 'E' visibility = 'public' isSpecification = 'false'
    isNavigable = 'false' aggregation = 'none'
    targetScope = 'instance' changeability = 'changeable'>
    <UML:AssociationEnd.multiplicity>
    <UML:Multiplicity/>
    </UML:AssociationEnd.multiplicity>
    <UML:AssociationEnd.participant>
    <UML:Classifier xmi.idref = 'F'/>
    </UML:AssociationEnd.participant>
    </UML:AssociationEnd>
    </UML:Association.connection>
    </UML:Association>

    </UML:Namespace.ownedElement>
    </UML:Model>
    <UML:TaggedValue xmi.id = 'XX.9'
    name = 'text'
    modelElement = 'XX.7'>
    <UML:TaggedValue.dataValue>

    </UML:TaggedValue.dataValue>
    </UML:TaggedValue>
    </XMI.content>
    </XMI>

    So, jetzt habe ich das Problem das in <UML:Association> (Zielstruktur) Information rein müssen, die ich zuerst mit Attributwerten die in <Connection> und <Instance> (Quellstruktur) stehen vergleichen muss und bei Übereinstimmung müssen andere Attributwerte in die Zielstruktur übernommen werden.

    In <In Connection> steht zum Beispiel drin, dass Maier eine Verbindung mit Müller hat. In der Zielstruktur soll aber drin stehen, dass die Nummer 123 mit der Nummer 234 eine Verbindung hat. Diese Nummer die zu Müller passt erhält man aus <Instance>, die andere Nummer die zu Maier passt erhält man aus einer anderen <Instance>.

    Ich habe es versucht folgendermaßen umzusetzen.

    <XMI>
    <XMI.content>
    <xsl:for-each select="MODELS">
    <xsl:variable name="VarMODELS" select="."/>
    <UML:Model>
    <UML:Namespace.ownedElement>
    <UML:Package>
    <UML:Namespace.ownedElement>
    <xsl:for-each select="MODEL">
    <xsl:variable name="VarMODEL" select="."/>
    <UML:Model>
    <UML:Namespace.ownedElement>
    <xsl:for-each select="INSTANCE">
    <xsl:choose>
    <xsl:when test="@class='actor'">
    <UML:Actor>
    <xsl:attribute name="xmi.id" separator=" ">
    <xsl:value-of select="@id"/>
    </xsl:attribute>
    </UML:Actor>
    </xsl:when>
    <xsl:when test="@class='use case'">
    <UML:UseCase>
    <xsl:attribute name="xmi.id" separator=" ">
    <xsl:value-of select="@id"/>
    </xsl:attribute>
    </UML:UseCase>
    </xsl:when>
    <xsl:when test="@class='Note'">
    <UML:Comment>
    </UML:Comment>
    </xsl:when>
    <xsl:when test="@class='system boundary'">
    <UML:system_boundary>
    </UML:system_boundary>
    </xsl:when>
    </xsl:choose>
    </xsl:for-each>


    <xsl:for-each select="CONNECTOR">
    <xsl:choose>
    <xsl:when test="@class='communicates'">
    <UML:Association>
    <xsl:attribute name="xmi.id" separator=" ">
    <xsl:value-of select="@id"/>
    </xsl:attribute>

    <UML:Association.connection>


    <UML:AssociationEnd visibility='public' isSpecification="false" isNavigable="false" aggregation="none" targetScope="instance" changeability="changeable">


    <xsl:variable name="VarClass" select="FROM/@class"/>
    <xsl:variable name="VarName" select="FROM/@instance"/>
    <xsl:for-each select="INSTANCE">
    <xsl:if test="@class=$VarClass">
    <xsl:if test="@name=$VarName">

    <xsl:value-of select="@id"/>
    </xsl:if>
    </xsl:if>
    </xsl:for-each>


    <UML:AssociationEnd.multiplicity>
    <UML:Multiplicity/>
    </UML:AssociationEnd.multiplicity>
    <UML:AssociationEnd.participant>
    <UML:Classifier xmi.idref="S.11"/>
    </UML:AssociationEnd.participant>
    </UML:AssociationEnd>

    <UML:AssociationEnd xmi.id="G.19" visibility="public" isSpecification="false" isNavigable="false" aggregation="none"
    </UML:AssociationEnd>
    </UML:Association.connection>
    </UML:Association>
    </xsl:when>
    </xsl:choose>
    </xsl:for-each>

    </UML:Namespace.ownedElement>
    </UML:Model>
    </xsl:for-each>
    </UML:Namespace.ownedElement>
    </UML:Package>
    </UML:Namespace.ownedElement>
    </UML:Model>
    </xsl:for-each>
    </XMI.content>
    </XMI>

    Die Stelle die interessant ist habe ich mal fett markiert. Hier erhalte ich keine Ausgabe, was muss ich anders machen, wo liegt mein Denkfehler?

    THX

    Opelk

  • #2
    Die XML-Struktur sagt bezogen auf die gewünschte Ausgabe exakt nichts aus. Ins Blaue geraten: Setze die beiden xsl:variable-Zeilen in den xsl:for-each-Block.

    BTW: <XML> ist eine schlechte Wahl, weil Namen nicht mit der xml-Zeichenfolge beginnen dürfen bzw. diese reserviert ist.

    Comment


    • #3
      Hi Herr Meinike,

      <XML> war nur ein Beispiel, stimmt war nicht clever.

      Die Quellstruktur hier ein wenig ausführlicher:

      <TestXML>
      <MODELS>
      <MODEL id="35467" name="TestModell">
      <MODELATTRIBUTES>
      <ATTRIBUTE>Test Modell</ATTRIBUTE>
      </MODELATTRIBUTES>
      <INSTANCE id="333" class="use case" name="Lesen">
      </INSTANCE>
      <INSTANCE id="444" class="use case" name="Schreiben">
      </INSTANCE>
      <INSTANCE id="555" class="actor" name="Leser">
      </INSTANCE>
      <CONNECTOR id="999" class="contains"><FROM instance="Lesen" class="use case"></FROM>
      <TO instance="Schreiben" class="use case"></TO>
      </CONNECTOR>
      <CONNECTOR id="888" class="Is inside"><FROM instance="Lesen" class="use case"></FROM>
      <TO instance="Leser" class="actor"></TO>
      </CONNECTOR>
      </MODEL>
      </MODELS>
      </TestXML>

      Und hier sind die Connectoren über die class und den name mit einander verknüpft. In der Zielstruktur sollen aber die id miteinander verknüpft werden. Dies Informationen kann man aus den Instance entnehmen.

      Ich hoffe hiermit können Sie mehr anfangen und bedanke mich recht herzlich für die Unterstützung.

      THX

      opelk

      Comment


      • #4
        Hallo Herr Meinike,

        folgende Struktur soll herauskommen:

        <?xml version = '1.0' encoding = 'Cp1252' ?>
        <XMI xmi.version = '1.1' xmlns:UML = '//org.omg/UML/1.3'>
        <XMI.header>
        <XMI.documentation>
        <XMI.exporter>
        TestSoftware
        </XMI.exporter>
        <XMI.exporterVersion>
        0.0
        </XMI.exporterVersion>
        </XMI.documentation>
        <XMI.metamodel xmi.name = 'UML' xmi.version = '1.4'/>
        </XMI.header>
        <XMI.content>
        <UML:Model xmi.id = '35467' name = 'TestModell' visibility = 'public'>
        <UML:Namespace.ownedElement>
        <UML:Package xmi.id = '0000'
        name = 'Test Package' visibility = 'package' isSpecification = 'false'
        isAbstract = 'false'>
        <UML:Namespace.ownedElement>
        <UML:Model xmi.id = '111111' name = 'Use Case View' visibility = 'public' isSpecification = 'false' isAbstract = 'false'>
        <UML:Namespace.ownedElement>
        <UML:Actor xmi.id = '555'
        name = 'Leser' visibility = 'package' isSpecification = 'false'
        isAbstract = 'false'>
        </UML:Actor>
        <UML:UseCase xmi.id = '333'
        name = 'Lesen' visibility = 'package' isSpecification = 'false'
        isAbstract = 'false'>
        </UML:UseCase>
        <UML:UseCase xmi.id = '444'
        name = 'Schreiben' visibility = 'package' isSpecification = 'false'
        isAbstract = 'false'>
        </UML:UseCase>

        <!--From Lesen to Schreiben -->
        <UML:Association xmi.id = '999'
        name = '{Lesen-Schreiben}' visibility = 'package' isSpecification = 'false'
        isAbstract = 'false' stereotype = 'XX.11'>
        <UML:Association.connection>
        <UML:AssociationEnd xmi.id = '333' visibility = 'public' isSpecification = 'false'
        isNavigable = 'false' aggregation = 'none'
        targetScope = 'instance' changeability = 'changeable'>
        <UML:AssociationEnd.multiplicity>
        <UML:Multiplicity/>
        </UML:AssociationEnd.multiplicity>
        <UML:AssociationEnd.participant>
        <UML:Classifier xmi.idref = 'S.333'/>
        </UML:AssociationEnd.participant>
        </UML:AssociationEnd>
        <UML:AssociationEnd xmi.id = '444' visibility = 'public' isSpecification = 'false'
        isNavigable = 'false' aggregation = 'none'
        targetScope = 'instance' changeability = 'changeable'>
        <UML:AssociationEnd.multiplicity>
        <UML:Multiplicity/>
        </UML:AssociationEnd.multiplicity>
        <UML:AssociationEnd.participant>
        <UML:Classifier xmi.idref = 'S.444'/>
        </UML:AssociationEnd.participant>
        </UML:AssociationEnd>
        </UML:Association.connection>
        </UML:Association>
        <!--From Leser to Lesen-->
        <UML:Association xmi.id = '888'
        name = '{Lesen-Leser}' visibility = 'package' isSpecification = 'false'
        isAbstract = 'false' stereotype = 'XX.12'>
        <UML:Association.connection>
        <UML:AssociationEnd xmi.id = '333' visibility = 'public' isSpecification = 'false'
        isNavigable = 'false' aggregation = 'none'
        targetScope = 'instance' changeability = 'changeable'>
        <UML:AssociationEnd.multiplicity>
        <UML:Multiplicity/>
        </UML:AssociationEnd.multiplicity>
        <UML:AssociationEnd.participant>
        <UML:Classifier xmi.idref = 'S.333'/>
        </UML:AssociationEnd.participant>
        </UML:AssociationEnd>
        <UML:AssociationEnd xmi.id = '555' visibility = 'public' isSpecification = 'false'
        isNavigable = 'false' aggregation = 'none'
        targetScope = 'instance' changeability = 'changeable'>
        <UML:AssociationEnd.multiplicity>
        <UML:Multiplicity/>
        </UML:AssociationEnd.multiplicity>
        <UML:AssociationEnd.participant>
        <UML:Classifier xmi.idref = 'S.555'/>
        </UML:AssociationEnd.participant>
        </UML:AssociationEnd>
        </UML:Association.connection>
        </UML:Association>

        <!--==================== communicate [Stereotype] ====================-->
        <UML:Stereotype xmi.id = 'XX.11'
        name = 'contains' visibility = 'public' isSpecification = 'false' icon = ''>
        <UML:Stereotype.baseClass>
        Association
        </UML:Stereotype.baseClass>
        <UML:Stereotype.extendedElement>
        <Foundation.Core.ModelElement xmi.idref = '999'/>
        </UML:Stereotype.extendedElement>
        </UML:Stereotype>
        <!--==================== communicate [Stereotype] ====================-->
        <UML:Stereotype xmi.id = 'XX.12'
        name = 'Is inside' visibility = 'public' isSpecification = 'false' icon = ''>
        <UML:Stereotype.baseClass>
        Association
        </UML:Stereotype.baseClass>
        <UML:Stereotype.extendedElement>
        <Foundation.Core.ModelElement xmi.idref = '888'/>
        </UML:Stereotype.extendedElement>
        </UML:Stereotype>

        </UML:Namespace.ownedElement>
        </UML:Model>
        <UML:TaggedValue xmi.id = 'XX.01'
        name = 'text'
        modelElement = 'XX.11'>
        <UML:TaggedValue.dataValue>
        Die ist ein Test
        </UML:TaggedValue.dataValue>
        </UML:TaggedValue>
        </XMI.content>
        </XMI>

        THX

        opelk
        Zuletzt editiert von opelk; 24.02.2009, 18:45.

        Comment


        • #5
          Wäre es möglich, das Problem an einem vereinfachten Beispiel darzustellen? Solche Codewüsten versteht wohl nur der Ersteller selbst.

          Comment


          • #6
            Hi,

            ich habe ein wenig mit Farben gespielt :-)

            Quelle:

            <TestXML>
            <MODELS>
            <MODEL id="35467" name="TestModell">
            <MODELATTRIBUTES>
            <ATTRIBUTE>Test Modell</ATTRIBUTE>
            </MODELATTRIBUTES>
            <INSTANCE id="333" class="use case" name="Lesen">
            </INSTANCE>
            <INSTANCE id="444" class="use case" name="Schreiben">
            </INSTANCE>
            <INSTANCE id="555" class="actor" name="Leser">
            </INSTANCE>
            <CONNECTOR id="999" class="contains"><FROM instance="Lesen" class="use case"></FROM>
            <TO instance="Schreiben" class="use case"></TO>
            </CONNECTOR>
            <CONNECTOR id="888" class="Is inside"><FROM instance="Lesen" class="use case"></FROM>
            <TO instance="Leser" class="actor"></TO>
            </CONNECTOR>
            </MODEL>
            </MODELS>
            </TestXML>

            Ziel:

            <XMI.content>
            <UML:Model>
            <UML:Namespace.ownedElement>
            <UML:Package>
            <UML:Namespace.ownedElement>
            <UML:Model xmi.id = '111111' name = 'Use Case View'>
            <UML:Namespace.ownedElement>
            <UML:UseCase xmi.id = '333' name = 'Lesen'></UML:UseCase>
            <UML:UseCase xmi.id = '444' name = 'Schreiben'></UML:UseCase>

            <!--From Lesen to Schreiben -->
            <UML:Association xmi.id = '999' name = '{Lesen-Schreiben}'>
            <UML:Association.connection>
            <UML:AssociationEnd xmi.id = '333'>
            <UML:AssociationEnd.multiplicity>
            <UML:Multiplicity/>
            </UML:AssociationEnd.multiplicity>
            <UML:AssociationEnd.participant>
            <UML:Classifier xmi.idref = 'S.333'/>
            </UML:AssociationEnd.participant>
            </UML:AssociationEnd>
            <UML:AssociationEnd xmi.id = '444'>
            <UML:AssociationEnd.multiplicity>
            <UML:Multiplicity/>
            </UML:AssociationEnd.multiplicity>
            <UML:AssociationEnd.participant>
            <UML:Classifier xmi.idref = 'S.444'/>
            </UML:AssociationEnd.participant>
            </UML:AssociationEnd>
            </UML:Association.connection>
            </UML:Association>

            </UML:Namespace.ownedElement>
            </UML:Model>
            </XMI.content>
            </XMI>

            Wie man hier sieht gehören die roten und blauen Sachen zusammen. In der Quelle hat man in <INSTANCE> infos über id, name, class. und in der <CONNECTOR> nur über name, class hier fehlt die id.
            In der Ziel datei werden für die Association die id benötigt und nicht name und class somit muss im Quell file gesucht werden welche id der (name, class) hat. Und dieses suchen und einfügen in die Zieldatei bekomme ich nicht hin.

            Hier benötige ich eure Hilfe.

            THX

            opelk

            Comment


            • #7
              Versuch, ausgehend vom letzten XML-Dokument mit Ansprache von CONNECTOR-Elementen und Suche der zugehörigen INSTANCE-ID:
              Code:
              <xsl:template match="TestXML/MODELS/MODEL">
                <test>
                  <xsl:apply-templates select="CONNECTOR"/>
                </test>
              </xsl:template>
              
              <xsl:template match="CONNECTOR">
                <id><xsl:value-of select="preceding-sibling::INSTANCE[@class = current()/FROM/@class and @name = current()/FROM/@instance]/@id"/></id>
              </xsl:template>
              Ergebnis:
              Code:
              <test>
                <id>333</id>
                <id>333</id>
              </test>

              Comment


              • #8
                Hi,


                es liefert ein Ergebnis, es sieht nicht schlecht aus, komme aber erst morgen dazu, es auszuprobieren.

                Herzlichen Dank

                opelk

                Comment


                • #9
                  Herr Meinike,


                  vielen, vielen Dank es funktioniert. (Hätte ich dieses Forum hier bereits früher aufgesucht hätte ich mir einige Stunden Suche erspart.)

                  Es sind noch ein paar Fragen aufgetaucht:

                  1.) Wenn ich {Name} als Ausgabe habe möchte (die Geschweiften Klammern sollen Teil der Ausgabe sein), dann funtkioniert dies hier nicht, was mach ich hier falsch:
                  <xsl:text>{</xsl:text> <xsl:value-of select="@name"/> <xsl:text>}</xsl:text>

                  2.) Dann habe ich noch eine Frage zu der Ausgabe, wenn ich in der Ausgabe kein " haben möchte sondern ' Wie mach ich dieses?

                  3. )Des Weiteren wie verwende ich einen Zeilnumbruch?
                  <xsl:comment>Dies ist ein Kommentar</xsl:comment> <xsl:text> </xsl:text>
                  Dies funtkioniert, aber gibt es noch eine elegantere Lösung?

                  Ich danke bereits im Vorfeld für die Beantwortung der Fragen.

                  Comment


                  • #10
                    Die geschweiften Klammern lassen sich mittels concat()-Funktion zusammensetzen:
                    Code:
                    <xsl:value-of select="concat('{',@name,'}')"/>
                    Für Umbrüche <xsl:text>&#xA;</xsl:text> verwenden. Die Art der Anführungszeichen bei Attributen wird vom Prozessor bei der Serialisierung der Ausgabe bestimmt. Vielleicht gibt die Prozessor-Doku etwas her.

                    Comment


                    • #11
                      Hi,

                      das war auch eine Idee von mir mit den geschweiften Klammer, funktioniert aber nicht.

                      Die Zeilenumbrüche funktionieren, danke.

                      Meine Absicht ist es, dass ich en XML-Datei in eine andere XML-Datei mit xsl und Prozessor umwandel, z.B. per Kommandozeile. Gibt es hier bereits fertige Prozessoren, die nicht in Java oder ähnliches eingebunden werden müssen.?

                      THX

                      Comment


                      • #12
                        Das funktioniert durchaus, wenn es für die Ausgabe in einem Element bestimmt ist. Bei einem Attribut entsprechend:
                        Code:
                        attributname="{concat('{',@name,'}')}"
                        Die roten Klammern stehen für ein Attribute Value Template und die grünen werden darin ausgegeben.
                        An der Kommandozeile lassen sich u. a. Saxon und AltovaXML ausführen.

                        Comment


                        • #13
                          Sorry,

                          aber wie meinen Sie das, so funtkioniert schon nicht.
                          Code:
                          <xsl:attribute name="name" separator=" ">
                          <xsl:value-of select="{concat('{',@name,'}')}"/>
                          </xsl:attribute>
                          Hier hatte ich eine Lösung, in der ich der Variablen $ConnectorName den entsprechenden Wert mit den Variablen zugewiesen habe.

                          Code:
                          <xsl:attribute name="name" separator=" ">
                          <xsl:value-of select="$ConnectorName"/>
                          </xsl:attribute>

                          Comment


                          • #14
                            Diese Wege sind zur Attributerzeugung möglich (beim ersten ohne umschließende Klammern {...}):

                            Code:
                            <ausgabeelement>
                              <xsl:attribute name="name">
                                <xsl:value-of select="concat('{',@name,'}')"/>
                              </xsl:attribute>
                              <!-- ... -->
                            </ausgabeelement>
                            
                            <ausgabeelement name="{concat('{',@name,'}')}">
                              <!-- ... -->
                            </ausgabeelement>
                            Bei Nutzung der Zwischenvariable müsste @name jeweils durch $ConnectorName ersetzt werden.

                            Hinweis: Das verwendete separator-Attribut ist erst unter XSLT 2.0 verfügbar!

                            Comment

                            Working...
                            X