Announcement

Collapse
No announcement yet.

XSL When-Bedingung funktioniert nicht

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

  • XSL When-Bedingung funktioniert nicht

    Hallo,

    ich versuche eine XSL-Transformation nach XML durchzuführen.

    Aus der folgenden XML Datei:
    <B id="1">
    <Filter id="10" use="opt">
    Year between {2007:2009}
    </Filter>
    </B>
    <B id="2">
    <Filter id="11" use="opt">
    Org in ('DB')
    </Filter>
    </B>

    will ich nach dieser XML-Datei transformieren:
    <B id="1">
    <Filter id="10" use="opt">
    <X type="interval">
    <From disp="2007" />
    <To disp="2009"
    </X>
    </Filter>
    </B>
    <B id="2">
    <Filter id="11" use="opt">
    <X type="String">
    <Y disp="DB" />
    </X>
    </Filter>
    </B>

    wenn der Inhalt von Filter "between" enthält werden drei Elemente erstellt
    und das Jahr 2007 und 2009 wird als Attributwert gesetzt.

    wenn der Inhalt von Filter "in" enthält werden zwei Elemente erstellt
    und DB wird als Attributwert gesetzt.

    Folgendes XSLT wende ich an:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xslutput method="xml" encoding="UTF-8" indent="yes"/>

    <xsl:attribute-set name="list1">
    <xsl:attribute name="type">string</xsl:attribute>
    </xsl:attribute-set>
    <xsl:attribute-set name="list2">
    <xsl:attribute name="disp">DB</xsl:attribute>
    </xsl:attribute-set>
    <xsl:attribute-set name="list3">
    <xsl:attribute name="type">interval</xsl:attribute>
    </xsl:attribute-set>
    <xsl:attribute-set name="list4">
    <xsl:attribute name="disp">2007</xsl:attribute>
    </xsl:attribute-set>
    <xsl:attribute-set name="list5">
    <xsl:attribute name="disp">2009</xsl:attribute>
    </xsl:attribute-set>

    <xsl:template match="@*|node()">
    <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    </xsl:template>

    <xsl:template match="Filter/text()">
    <xsl:choose>
    <xsl:when test="contains(text(), 'in')">
    <xsl:element name="x" use-attribute-sets="list1">
    <xsl:apply-templates />
    <xsl:element name="y" use-attribute-sets="list2">
    <xsl:apply-templates />
    </xsl:element>
    </xsl:element>
    </xsl:when>
    <xsl:when test="contains(text(), 'between')">
    <xsl:element name="x" use-attribute-sets="list3">
    <xsl:apply-templates />
    <xsl:element name="from" use-attribute-sets="list4">
    <xsl:apply-templates />
    <xsl:element name="to" use-attribute-sets="list5">
    <xsl:apply-templates />
    </xsl:element>
    </xsl:when>
    </xsl:choose>
    </xsl:template>
    </xsl:stylesheet>

    aber das funktioniert nicht.

    Könnt ihr mir helfen?

    Vielen Dank

  • #2
    Hier ist offenbar die Ausgabe des Eingangsbaumes mit speziellen Änderungen gesucht. Deshalb bietet sich die Kombination des Identitäts-Templates (dieses würde allein das Originaldokument reproduzieren) mit zusätzlichen Templates zur Umsetzung der Filter-Änderungen an:
    Code:
    <xsl:template match="@* | node()">
      <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Filter[contains(.,'between')]">
      <xsl:apply-templates select="@*"/>
      <X type="interval"> 
        <From disp="{substring(substring-before(.,':'),string-length(.)-10,4)}"/>
        <To disp="{substring(substring-after(.,':'),1,4)}"/>
      </X>
    </xsl:template>
    
    <xsl:template match="Filter[contains(.,'in')]">
      <xsl:apply-templates select="@*"/>
      <X type="String"> 
        <Y disp="DB"/>
      </X>
    </xsl:template>

    Comment


    • #3
      hi,

      ich bekomme die Warnung:
      "Cannot write an attribute node when no element start tag is open"

      wie bekomme ich die Warnung weg?

      Comment


      • #4
        Welcher Prozessor gibt diese Meldung aus? Mit dem Beispielcode funktioniert es problemlos. Vermutlich ist das XML-Dokument anders aufgebaut.

        Comment


        • #5
          ich verwende Saxon.

          Comment


          • #6
            Ok, mit Saxon B 9.1.0.6 nachvollziehbar, mit AltovaXML 2009 hatte es funktioniert. Probiere es alternativ so (Ausgabe der Filterelemente explizit hinzugefügt):
            Code:
            <xsl:template match="@* | node()">
              <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
              </xsl:copy>
            </xsl:template>
            
            <xsl:template match="Filter[contains(.,'between')]">
              <Filter>
                <xsl:apply-templates select="@*"/>
                <X type="interval">
                  <From disp="{substring(substring-before(.,':'),string-length(.)-10,4)}"/>
                  <To disp="{substring(substring-after(.,':'),1,4)}"/>
                </X>
              </Filter>
            </xsl:template>
            
            <xsl:template match="Filter[contains(.,'in')]">
              <Filter>
                <xsl:apply-templates select="@*"/>
                <X type="String"> 
                  <Y disp="DB"/>
                </X>
              </Filter>
            </xsl:template>

            Comment


            • #7
              Hallo,

              es läuft ohne Warnung...
              vielen Dank für deine Hilfe

              Grüsse

              Comment

              Working...
              X