Frage

Ich bin mit XSLT und XML.

Das erste, was ich auf zwei xml zu arbeiten werde.

Erste XML:

<?xml version="1.0"?>
<tcm:ListItems xmlns:tcm="http://www.tridion.com/ContentManager/5.0" ID="tcm:232-83752-2" Managed="10682">  
  <tcm:Item ID="tcm:232-564598" Title="010 News Mapping"/>
  <tcm:Item ID="tcm:232-564599" Title="020 CUGOs"/>
  <tcm:Item ID="tcm:232-614307" Title="030 Reserved Urls"/>
</tcm:ListItems>

Die Second XML werden wir es über ID dh tcm erhalten mit: 232-564598 etc, unter einer der xml ist für ID tcm: 232-564598 und andere IDs gleichen Typs werden mit der XML.

<tcm:Component ID="tcm:229-564598" IsEditable="false" xmlns:tcm="http://www.tridion.com/ContentManager/5.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <tcm:Data>
    <tcm:Content>
      <MappingCollection xmlns="uuid:922EEC29-2DE3-4BA1-A46A-A300CB8FA85F">
        <VanityUrl>
          <old>mbp</old>
          <new>/SessionHandler.aspx?pageurl=/BP.aspx&amp;pub=/english&amp;section=IBE&amp;j=f</new>
          <dateAdded>2010-05-03T14:45:00</dateAdded>
          <comments> News mapping </comments>
        </VanityUrl>
        <VanityUrl>
          <old>about/news</old>
          <new>about/news/news.aspx</new>
          <dateAdded>2010-05-03T14:45:00</dateAdded>
          <comments> News mapping </comments>
        </VanityUrl>
      </MappingCollection>
    </tcm:Content>
  </tcm:Data>
</tcm:Component>

Ich versuche unter Format XML erhalten über beiden XMLs verwendet wird.

<?xml version="1.0" encoding="UTF-8"?>
<mappings>
    <!-- News mapping -->
    <mapping old="mbp" new="/SessionHandler.aspx?pageurl=/BP.aspx&amp;pub=/english&amp;section=IBE&amp;j=f"/>
    <mapping old="about/news" new="about/news/news.aspx"/>
    <!-- CUGO's-->
    <mapping old="/nhs" new="/cugo.aspx?promoCode=UKNHS01&amp;pub=/uk/english"/>
    <mapping old="/hk/ukstudentfare" new="/cugo.aspx?promoCode=HKSTU10&amp;pub=/hk/Chinese"/>
</mappings> 

Und hier ist mein XSLT, wo ich versuche erzeugt das obige XML-Format, aber es funktioniert nicht für mich. Bitte beachten Sie erste xml ist primären xml, die unter XSLT transformiert werden mit

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tcm="http://www.tridion.com/ContentManager/5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:em="http://www.espire.com/tridion/schemas" xmlns:tcmse="http://www.tridion.com/ContentManager/5.1/TcmScriptAssistant" exclude-result-prefixes="em xlink tcmse tcm">
  <xsl:output method="xml" version="1.0" encoding="UTF-16" indent="yes"/>
  <!-- root match-->
  <xsl:template match="tcm:ListItems">
    <mappings>
      <xsl:apply-templates select="tcm:Item"/>
    </mappings>
  </xsl:template>
  <xsl:template match="tcm:Item">
      <xsl:variable name="doc" select="document(@ID)"/>
    <xsl:if test="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:comments">
      <xsl:comment>
        <xsl:value-of select="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:comments"/>
      </xsl:comment>
    </xsl:if>  
    <xsl:for-each select="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl">
        <xsl:element name="mapping">
          <xsl:if test="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:old">
            <xsl:attribute name="old">
              <xsl:value-of select="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:old"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:if test="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:new">
            <xsl:attribute name="new">
              <xsl:value-of select="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:new"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:if test="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:dateAdded">
            <xsl:attribute name="dateAdded">
              <xsl:value-of select="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:dateAdded"/>
            </xsl:attribute>
          </xsl:if>
        </xsl:element>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

In über xslt Ich bin in der Lage die Datenschleife zu erhalten, ist auch richtig, geht aber die Daten, die gleichen worden kommt, ist, ich meine Schleife korrekt ausführt, aber der Knotenwert ist die gleiche

Bitte vorschlagen!

War es hilfreich?

Lösung

Dieses Sheet:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ns="uuid:922EEC29-2DE3-4BA1-A46A-A300CB8FA85F"
 xmlns:tcm="http://www.tridion.com/ContentManager/5.0"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 exclude-result-prefixes="ns tcm msxsl">
    <xsl:strip-space elements="*"/>
    <xsl:key name="kVanityByComment" match="ns:VanityUrl" use="ns:comments"/>
    <xsl:template match="/">
        <xsl:variable name="vSourcesRTF">
            <xsl:copy-of select="document(tcm:ListItems/tcm:Item/@ID)"/>
        </xsl:variable>
        <mappings>
            <xsl:apply-templates select="msxsl:node-set($vSourcesRTF)/node()"/>
        </mappings>
    </xsl:template>
    <xsl:template match="ns:VanityUrl"/>
    <xsl:template match="ns:VanityUrl[generate-id()=
                                      generate-id(key('kVanityByComment',
                                                      ns:comments)[1])]">
        <xsl:comment>
            <xsl:value-of select="ns:comments"/>
        </xsl:comment>
        <xsl:apply-templates select="key('kVanityByComment',
                                         ns:comments)"
                             mode="output"/>
    </xsl:template>
    <xsl:template match="ns:VanityUrl" mode="output">
        <mapping>
            <xsl:apply-templates/>
        </mapping>
    </xsl:template>
    <xsl:template match="ns:VanityUrl/ns:comments" priority="1"/>
    <xsl:template match="ns:VanityUrl/*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

Mit diesem Eingang:

<tcm:ListItems xmlns:tcm="http://www.tridion.com/ContentManager/5.0" ID="tcm:232-83752-2" Managed="10682">
  <tcm:Item ID="229-564598" Title="010 News Mapping"/>
  <tcm:Item ID="229-564598" Title="020 CUGOs"/>
  <tcm:Item ID="229-564598" Title="030 Reserved Urls"/>
</tcm:ListItems>

Und diese externe Quelle mit 229-564598 URI:

<tcm:Component ID="tcm:229-564598" IsEditable="false" xmlns:tcm="http://www.tridion.com/ContentManager/5.0" xmlns:xlink="http://www.w3.org/1999/xlink">
  <tcm:Data>
    <tcm:Content>
      <MappingCollection xmlns="uuid:922EEC29-2DE3-4BA1-A46A-A300CB8FA85F">
        <VanityUrl>
          <old>mbp</old>
          <new>/SessionHandler.aspx?pageurl=/BP.aspx&amp;pub=/english&amp;section=IBE&amp;j=f</new>
          <dateAdded>2010-05-03T14:45:00</dateAdded>
          <comments> News mapping </comments>
        </VanityUrl>
        <VanityUrl>
          <old>about/news</old>
          <new>about/news/news.aspx</new>
          <dateAdded>2010-05-03T14:45:00</dateAdded>
          <comments> News mapping </comments>
        </VanityUrl>
      </MappingCollection>
    </tcm:Content>
  </tcm:Data>
</tcm:Component>

Ausgabe:

<mappings>
    <!-- News mapping -->
    <mapping old="mbp" 
             new="/SessionHandler.aspx?pageurl=/BP.aspx&amp;pub=/english&amp;section=IBE&amp;j=f"
             dateAdded="2010-05-03T14:45:00"></mapping>
    <mapping old="about/news"
             new="about/news/news.aspx"
             dateAdded="2010-05-03T14:45:00"></mapping>
</mappings>

Bearbeiten :. Mehrere Eingangsquellen

Andere Tipps

Ja, die Änderung, die Sie gemacht ist in der Tat entscheidend. : -)

Was die for-each-Schleife macht, ist jedes <em:VanityUrl> Element wählen Sie Ihre XPath Ausdruck übereinstimmen, machen, dass Element den Kontextknoten für das, was in der for-each (die template genannt, obwohl es kein <xsl:template> ) und dann instantiate dass innere Vorlage mit dem neuen Kontextknoten.

Wenn Sie verwenden würden weiter „$ doc / ...“ innerhalb der for-Schleife jeden Sie den Kontextknoten wurden wegzuwerfen, so dass die for-each wurde keine Wirkung (außer zu wiederholen n-mal).

Ihre <xsl:if test="$doc/..."> Aussagen wurden die Bewertung, ob es eine solche Knoten in dem gesamten Dokument statt im Kontext Element <em:VanityUrl>.

Die <xsl:value-of> Aussage achtet nur auf dem ersten Knoten in der ausgewählten nodeset, so dass Sie immer waren den Wert aus der immer zuerst <em:VanityUrl>, unabhängig vom Kontext Knoten.

Wenn Sie begann die Auswahl und Prüfung in Bezug auf den Kontextknoten:

    <xsl:if test="em:old">

wurde alles besser. : -)

Sie bat um einen wertvollen Beitrag. Aus stilistischen Gründen, können Sie Ihre <xsl:if> Tests mit <xsl:apply-templates> ersetzen. (Für eine Sache, die Sie @Dimitre Novatchev glücklich machen. :-) Also

<xsl:if test="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:comments">
  <xsl:comment>
    <xsl:value-of select="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:comments"/>
  </xsl:comment>
</xsl:if>

wird

<xsl:apply-templates select="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:comments" />

und dann müssen Sie eine eigene Vorlage für die:

<xsl:template match="em:comments">
  <xsl:comment>
    <xsl:value-of select="."/>
  </xsl:comment>
</xsl:template>

Es gibt mehrere Vorteile, das zu tun. Die größte ist, dass Sie nicht so lange XPath-Ausdruck duplizieren müssen, was war fehleranfällig, wenn der Ausdruck jemals geändert werden muß. Wenn es keine em sind: Kommentar Elemente, die apply-templates werden nichts tun, wird so keinen Kommentar abgeben

.

Es modularisiert auch Ihr Stylesheet, so dass Sie ändern, wie em: Kommentare gemacht werden, getrennt von wo auch immer sie auftreten können. Das mag nicht allzu wichtig in einfachen XML-Dokumenten, bei denen em: Kommentare nur an einer Stelle auftreten, aber es ist der Stil, die besten Vorteil von XSLT Macht nimmt. Beachten Sie auch, dass diese Version Ausgabe mehrere Kommentare geändert, wenn es mehrere em sind: Kommentare, die Ihre Version nicht. Auch hier haben Sie wahrscheinlich nicht ein Vielfaches der Eingangs, so kann es nicht Sache.

Ebenso für die Ausgabe-Attribute:

    <xsl:if test="em:old">
      <xsl:attribute name="old">
        <xsl:value-of select="em:old"/>
      </xsl:attribute>
    </xsl:if>

kann sich

    <xsl:apply-templates select="em:old[1]" />

mit einer separaten Vorlage

<xsl:template match="em:old">
   <xsl:attribute name="old">
     <xsl:value-of select="."/>
   </xsl:attribute>
</xsl:template>

Beachten Sie die [1], die mehrere old="..." Attribute Ausgang für das gleiche Element versucht, vermeidet, wenn der Eingang em: VanityUrl hat mehrere em: alte Elemente. Das wäre Grund Ihr Stylesheet einen Fehler zu erhöhen. Aber vielleicht haben Sie wollen einen Fehler in diesem Fall zu erhöhen. Wenn ja, sind Sie wahrscheinlich bereits Ihre Eingabe-XML-Validierung.

In der Tat, können Sie die Anwendung-Vorlagen und die Vorlage verallgemeinern hier auf alle drei Attribute anwenden:

    <xsl:apply-templates select="em:old[1] | em:new[1] | em:dateAdded[1]" />

Auch wenn eines dieser Elemente nicht vorhanden ist, wird nichts für sie getan wird (kein leeres Attribut produziert werden). Die Vorlage:

<xsl:template match="em:old | em:new | em:dateAdded">
   <xsl:attribute name="{local-name()}">
     <xsl:value-of select="."/>
   </xsl:attribute>
</xsl:template>

local-name() gibt uns den Namen des Elements, ohne das Namespacepräfix.

Update:

Eine weitere Möglichkeit, Griff, einen Modus zu verwenden wäre:

    <xsl:apply-templates select="em:old[1] | em:new[1] | em:dateAdded[1]"
      mode="make-attribute" />

<xsl:template match="em:*" mode="make-attribute">
   <xsl:attribute name="{local-name()}">
     <xsl:value-of select="."/>
   </xsl:attribute>
</xsl:template>

Dann wird Ihr Make-Attribut Vorlage kann von überall verwendet werden, und die Übereinstimmungsmuster haben nicht alle möglichen Element anzupassen aktualisiert werden Sie ein Attribut aus machen könnten wollen.

Das einzige, was ich sagen kann, ist, dass die Verwendung von Namensräumen oben ist verwirrend ... es nicht funktionieren sollte, wie sie ist. Z.B. Ihr Stylesheet verwendet diese NamespaceURI für Elemente wie VanityURL:

 "http://www.espire.com/tridion/schemas"

aber das zweite Eingabedokument verwendet diesen NamespaceURI für diese Elemente:

 "uuid:922EEC29-2DE3-4BA1-A46A-A300CB8FA85F"

Es spielt keine Rolle, dass der Namespacepräfixe unterschiedlich ist ( „em:“ vs. Standard), aber der Namespace-URIs muß übereinstimmen. Ich denke, VanityURL NamespaceURI muss geändert haben, oder aber Ihr Stylesheet würde nicht funktionieren ...

HTH!

Sie können versuchen, diese auch !!

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tcm="http://www.tridion.com/ContentManager/5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:em="http://www.espire.com/tridion/schemas" xmlns:tcmse="http://www.tridion.com/ContentManager/5.1/TcmScriptAssistant" exclude-result-prefixes="em xlink tcmse tcm">
  <xsl:output method="xml" version="1.0" encoding="UTF-16" indent="yes"/>     
  <!-- root match-->
  <xsl:template match="tcm:ListItems">
    <mappings>
      <xsl:apply-templates select="tcm:Item"/>
    </mappings>
  </xsl:template>
  <xsl:template match="tcm:Item">
    <xsl:variable name="doc" select="document(@ID)"/>
    <xsl:if test="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:comments">
      <xsl:comment>
        <xsl:value-of select="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl/em:comments"/>
      </xsl:comment>
    </xsl:if>
    <xsl:for-each select="$doc/tcm:Component/tcm:Data/tcm:Content/em:MappingCollection/em:VanityUrl">
      <xsl:element name="mapping">
        <xsl:if test="em:old">
          <xsl:attribute name="old">
            <xsl:value-of select="em:old"/>
          </xsl:attribute>
        </xsl:if>
        <xsl:if test="em:new">
          <xsl:attribute name="new">
            <xsl:value-of select="em:new"/>
          </xsl:attribute>
        </xsl:if>
        <xsl:if test="em:dateAdded">
          <xsl:attribute name="dateAdded">
            <xsl:value-of select="em:dateAdded"/>
          </xsl:attribute>
        </xsl:if>
      </xsl:element>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top