Announcement

Collapse
No announcement yet.

copy or copy-of

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

  • copy or copy-of

    Hallo!

    Ich vermute diese Frage wird sich mal wieder als total einfach herausstellen, aber ich bin grade etwas am verzweifeln. Habe mir auch schon unzählige Seiten dazu angeguckt, komme aber trotzdem nicht weiter.

    Mein Problem:

    Ich möchte durch einen XML-Text gehen und die namen der Attribute überprüfen. Sobald ich den richtigen gefunden habe, soll nur in der zeile was geändert werden, sonst soll die Datei zeile für Zeile kopiert werden.

    hier mein Ansatz:
    Code:
    <xsl:template match="/">
    		<name>
    			<xsl:for-each select="/.//*">
    				<xsl:choose>
    					<xsl:when test="contains(@name, 'press')">
    						<xsl:call-template name="getPress"/>
    					</xsl:when>
    					<xsl:otherwise>
    					<!-- hier sollte etwas kommen womit ich eben nur eine Zeile kopiere und sonst nichts -->	
    					</xsl:otherwise>
    				</xsl:choose>
    			</xsl:for-each>
    		</name>
    	</xsl:template>
    Das Problem ist, dass ich mit "copy-of" zu viel und mit "copy" nicht genug kopiere. Ich muss auch zugeben, dass ich mit dem Befehl "copy" oder dem "use-attribute-sets" nicht so ganz klar komme. Es gibt auch immer wieder Beispiele von "copy" in Verbindung mit "apply-templates", aber diese konnte ich auch nicht auf mein Problem anwenden...

    Freue mich sehr über jeden Vorschlag!

    Gruß
    Alex

  • #2
    Es hängt natürlich wie immer von eigentlichen XML-Kontext ab. Probiere es mit <xsl:copy-of select="child::node()"/>.

    Comment


    • #3
      Es ist eigentlich eine xsd-datei, die ich als XML gespeichert habe um diese bearbeiten zu können.

      hier der Teil, der bearbeitet werden soll:
      Code:
      <xs:element name="press_a">
      	<xs:complexType>
      	 	<xs:simpleContent>
      			<xs:extension base="xs:float">
      				<xs:attribute name="uom" type="xs:string" use="required"/>
      				<xs:attribute name="tata" type="xs:string" use="required"/>
      				<xs:attribute name="lala" type="xs:string" use="required"/>
      				<xs:attribute name="new_type" type="xs:string" use="required"/>
      			</xs:extension>
      		</xs:simpleContent>
      	</xs:complexType>
      </xs:element>
      Element namens "press_a" befindet sich wiederum in einem größeren Kontext, duch den ich durchgehen möchte und sobald der Name "press" auftaucht, wird das Attribut mit dem Namen "new_type" bearbeitet bzw. wird an der Stelle ein template aufgerufen, das die Zeile ändern soll.

      Alles Andere, davor und danach soll bloß kopiert werden. Es hört sich echt einfach an, aber es klappt nicht so wie ich es will :-(

      Mit dem Befehl oben klappt es leider noch nicht...
      Zuletzt editiert von w_ing; 12.08.2008, 12:09.

      Comment


      • #4
        Was ich dazu sagen muss ist, dass man vorher nicht weiß, wie "tief" im Gesamtkontext die nötige Zeile ist. Ich kann daher nicht einfach ein neues Konstrukt bauen, wo ich dann bloß die nötige Zeile auslesen und einbauen könnte. Es muss wirklich so laufen, dass alles bis auf die Zeile mit dem Attribut "new_type" nach und nach kopiert wird. Ich zweifel allerdings mittlerweile daran, dass es geht...

        Comment


        • #5
          Help

          Hallo Leute!

          Hat wirklich niemand eine Idee?? Oder ist es doch zu einfach? Muss zugeben, ich schlage mich mit dem Problem seit Tagen rum und bekomme kein zufriedenstellendes Ergebnis. Was ich brauche ist quasi eine erweiterte Funktionalität des Befehls Strg+H. Die oben angegebene Liste soll kopiert werden, nur die eine Zeile wo das Attribut den Namen "new_type" hat wird insofern verändert, dass statt "typ="xs:string" nun "typ="press" stehen soll. Der Rest soll einfach in der vorhandenen Reihenfolge kopiert werden...

          Ich komme echt nicht drauf.

          Vielen Dank im Voraus für weitere Vorschläge!!

          Comment


          • #6
            Probiere es mit einem Identitäts-Template zum Kopieren aller Inhalte und der speziellen Behandlung des zu ändernden type-Attributes:
            Code:
            <xsl:template match="@*|node()">
              <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
              </xsl:copy>
            </xsl:template>
            
            <xsl:template match="attribute::type[.='xs:string'][../attribute::name[.='new_type']]">
              <xsl:attribute name="type">press</xsl:attribute>
            </xsl:template>
            Im Ergebnis steht die geänderte Zeile:
            Code:
            <xs:attribute name="new_type" type="press" use="required"/>

            Comment


            • #7
              Ich versuche das Problem gerade anders anzugehen:

              Also ich habe eine XML-Datei, die die Form eines Baumes hat. Wann immer in einer der Unterknoten/Kinder/Blätter ein Element auftaucht mit dem Attribut "name" das den Wert "data" hat soll ein Template aufgerufen werden.

              Mein Ansatz
              Code:
              <xsl:template match="/">
              		<xsl:for-each select="/.//*">
              				<xsl:choose>
              					<xsl:when test="contains(@name, 'data')">
              						<hierdata/>
              					</xsl:when>
              				</xsl:choose>
              		</xsl:for-each>
              	</xsl:template>
              scheint mir nicht besonders richtig zu sein. Kann ich an der Stelle auch irgendwie mit dem Befehl "apply-templates" arbeiten??

              Bin sehr dankbar für jede Hilfe!!

              Comment


              • #8
                Hallo Thomas!!

                Du bist ein Zauberer!! Es funktioniert fast. Aber schon mal vielen Dank!!! Das einzige Problem ist nur noch, dass man vorher nachschauen muss, ob das Oberlement "press" im Namen enthält. Also z.B. "press_a" wie hier in der Beispielsdatei. Kann aber auch z.B. "press_b" oder sonst etwas mit press sein. Das Problem ist nämlich, dass es auch Elemente gibt, die ebenfalls ein Attribut mit dem Namen "new_type" haben können, wo aber etwas anderes rein soll. Zum Beispiel kann das Oberelement "temp" heißen, dann käme bei "new_type" eben "temperature" rein usw...

                Bedanke mich auf jeden Fall schon mal herzlichst für die große Hilfe!!!

                Comment


                • #9
                  Dann prüfe noch, ob es ein passendes Vorfahrenelement gibt (ancestor-Achse):
                  Code:
                  <xsl:template match="attribute::type[.='xs:string'][../attribute::name[.='new_type']][ancestor::xs:element[@name='press_a']]">
                    <xsl:attribute name="type">press</xsl:attribute>
                  </xsl:template>

                  Comment


                  • #10
                    JAAAAAAAA!!!!!!!!!!!!!
                    Es klappt!!!!!

                    VIELEN DANK THOMAS!!!!

                    Comment


                    • #11
                      Noch eine kurze Zusatzfrage:

                      Wie mache ich das, wenn ich zusätzlich zu dem was da jetzt gemacht wird noch ein neues "Attribut" in dem jeweiligen Attribut erstellen möchte? attribute-set?

                      Was ich brauche ist, dass nun zusätzlich in dieser Liste:

                      Code:
                      <xs:element name="press_a">
                      	<xs:complexType>
                      	 	<xs:simpleContent>
                      			<xs:extension base="xs:float">
                      				<xs:attribute name="uom" type="xs:string" use="required"/>
                      				<xs:attribute name="tata" type="xs:string" use="required"/>
                      				<xs:attribute name="lala" type="xs:string" use="required"/>
                      				<xs:attribute name="new_type" type="xs:string" use="required"/>
                      			</xs:extension>
                      		</xs:simpleContent>
                      	</xs:complexType>
                      </xs:element>
                      sobald z.B. der Name "tata" auftaucht, soll da ein fixer Wert eingetragen werden. z.B.: "1"
                      Also in etwa so:
                      Code:
                      <xs:attribute name="uom" type="xs:string" use="required" fixed="1"/>
                      Es wird hier also nichts verändert, sondern nur ein neuer Wert eingetragen.

                      Vielen Dank im Voraus!!

                      Comment


                      • #12
                        Habe das jetzt erst einmal so gelöst:

                        Code:
                        <xsl:template match="attribute::type[.='xs:string'][../attribute::name[.='uom']][ancestor::xs:element[contains(@name, '_a')]]">
                        		<xsl:attribute name="type">xs:string</xsl:attribute>
                        		<xsl:attribute name="fixed">a</xsl:attribute>
                        	</xsl:template>
                        Ist wahrscheinlich nicht besonders elegant aber dann bin ich auf jeden Fall in der richtigen Ebene. Sonst klappt es nicht :-/

                        Comment


                        • #13
                          Das sollte so funktionieren, wobei das type-Attribut nicht nochmal erzeugt werden braucht.

                          Comment


                          • #14
                            ja, es verschwindet aber sonst... Ich glaube, da man danach sucht, wird auch erwartet, dass es verändert wird?

                            Comment


                            • #15
                              Sofern die gestern thematisierte Identitäts-Transformation im Spiel ist, sollte das Attribut mit kopiert werden und die Erweiterung kommt hinzu. Davon ging ich aus.

                              Comment

                              Working...
                              X