String in XSLT teilen

RicoTT

Mitglied
Hallo zusammen!

Ich möchte eine XML mit folgendem Node einlesen:
Code:
<Property FormattingType="0" FormattingLength="32" FormattingRAlign="1">
<PropertyName>Zusatzfeld </PropertyName>
<PropertyValue>['COM1', 'COM2', 'COM2']</PropertyValue>
</Property>
Daraus soll dann für jedes Element unter Property Value
ein neues Item erstellt werden.
Code:
<ITEM>
      <NAME>COM1</NAME>
</ITEM>
<ITEM>
      <NAME>COM2</NAME>
</ITEM>
<ITEM>
      <NAME>COM3</NAME>
</ITEM>

Mein Problem liegt jetzt darin den eingelesenen String zu teilen.
Habe zwar einige Beispiele gefunden, allerdings haben mir diese noch nicht so richtig helfen können.
http://www.codeproject.com/Questions/66195/Need-XSL-to-split-a-string-from-XML-input

Wäre super, wenn mir jemand helfen könnte.

Danke!
 
K

kneitzel

Gast
Also Du hast einen Link zur Lösung ja schon gepostet. Und wir hatten vor Kurzem ja schon einen Thread bezüglich Transformationen, bei dem ich wohl auch Links zu Tutorials gepostet habe. (Wenn nicht: Google bringt da ja sehr viele Treffer.)

Woran scheitert es? Was verstehst Du bei der Problematik bzw. bei der angebotenen Lösung auf der Webseite nicht? Ich sehe im Augenblick keinen Ansatzpunkt, um Dir wirklich effektiv mit Erläuterungen weiter zu helfen.

Ich habe mal einfach ein paar Dinge in der Lösung von dem Thread angepasst und einige Zwischenschritte mit ausgegeben, so dass Du es vielleicht leichter hast, die Lösung nachzuvollziehen.
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
            <xsl:apply-templates select="Property"/>
    </xsl:template>

    <xsl:template match="Property">
        <xsl:call-template name="SplitLinks">
            <xsl:with-param name="ComList" select="PropertyValue/text()"/>
        </xsl:call-template>
    </xsl:template>

    <!-- recursive template for splitting links -->
    <xsl:template name="SplitLinks">
        <xsl:param name="ComList"/>
        <Call> <xsl:value-of select="$ComList" /> </Call>
        <xsl:variable name="vCountSeparators" select="string-length($ComList) - string-length(translate($ComList,',',''))"/>
        <vCountSeparators> <xsl:value-of select="$vCountSeparators"/> </vCountSeparators>

        <xsl:choose>
            <xsl:when test="$vCountSeparators = 0">
              <ITEM>
                <NAME>
                    <xsl:variable name='t1' select="$ComList" />
                    <xsl:variable name='t2' select='substring-after($t1,"&apos;")' />
                    <xsl:variable name='t3' select='substring-before($t2,"&apos;")' />
                    <T1><xsl:value-of select="$t1"/></T1>
                    <T2><xsl:value-of select="$t2"/></T2>
                    <T3><xsl:value-of select="$t3"/></T3>
                </NAME>
              </ITEM>
            </xsl:when>

            <xsl:when test="$vCountSeparators &gt;= 1">
            <ITEM>
              <NAME>
                    <xsl:variable name='t1' select="substring-before($ComList,',')" />
                    <xsl:variable name='t2' select='substring-after($t1,"&apos;")' />
                    <xsl:variable name='t3' select='substring-before($t2,"&apos;")' />
                    <T1><xsl:value-of select="$t1"/></T1>
                    <T2><xsl:value-of select="$t2"/></T2>
                    <T3><xsl:value-of select="$t3"/></T3>
              </NAME>
            </ITEM>
                <!-- recursive call -->
                <xsl:call-template name="SplitLinks">
                    <xsl:with-param name="ComList" select="substring-after($ComList,',')"/>
                </xsl:call-template>
            </xsl:when>

        </xsl:choose>

     </xsl:template>
</xsl:stylesheet>

Also der Aufbau ist generell ganz einfach:
- Globales template (match="/") - Dort habe ich mal einfach ein root Element "result" eingefügt - das kannst Du aber auch raus nehmen. Wichtig ist hier nur, dass wir jetzt das Property Element auswerten wollen. Also sozusagen der Aufruf für das Property Element.
- Property template - Hier wird einfach nur das splitLinks (Name habe ich aus Deinem Link einfach beibehalten. Sollte man noch umbenennen) aufgerufen. Als Parameter wird der Inhalt von PropertyValue übergeben.
- splitLinks template. Dieses wird ja aufgerufen. Damit deutlich wird, was da passiert, gebe ich einfach einmal ein paar Informationen aus. In Call schreibe ich den Parameter und dann gebe ich noch in Count die Anzahl der Separatoren an. (Bei der Lösung ist wichtig, dass in einem String NIE der Separator vorkommt. Das wäre hier fatal.)
- splitLinks ist einfach eine Rekursion. Bei 0 Separatoren wird der Inhalt direkt ausgegeben. Bei mindestens einem Separator, wird der String vor dem Separator ausgegeben und dann splitLinks rekursiv aufgerufen mit dem Text nach dem Separator.
- Die Ausgabe würde hier noch die ' und auch die [ und ] beinhalten. Die schneide ich einfach ab indem ich nur den Text nach und vor dem ' (&apos) ausgebe. Das habe ich hier einfach mit Hilfvariablen t1, t2 und t3 gemacht - das wäre nicht zwingend nötig. Und ich gebe diese Variablen in entsprechenden Elementen aus.
Zur Vereinfachung sollte man evt ein template Ausgabe erstellen, dass den Text als Parameter bekommt und dass dann die Entfernung der ' durchführt. Dann hat man den Code nicht doppelt. Aber das muss nicht sein. Man kann auch die selects alle ineinander veschachteln um nur einen Ausdruck zu erhalten. Das war jetzt halt nur aufgesplittet um Dir auch die Ergebnisse vor Augen zu führen.

Und wenn man das dann testet (z.B. unter http://xslttest.appspot.com/) dann kann man als XML angeben:
Code:
<Property FormattingType="0" FormattingLength="32" FormattingRAlign="1">
  <PropertyName>Zusatzfeld </PropertyName>
  <PropertyValue>['COM1', 'COM2', 'COM2']</PropertyValue>
</Property>

und erhält dann:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<Call>['COM1', 'COM2', 'COM2']</Call>
<vCountSeparators>2</vCountSeparators>
<ITEM>
   <NAME>
      <T1>['COM1'</T1>
      <T2>COM1'</T2>
      <T3>COM1</T3>
   </NAME>
</ITEM>
<Call> 'COM2', 'COM2']</Call>
<vCountSeparators>1</vCountSeparators>
<ITEM>
   <NAME>
      <T1> 'COM2'</T1>
      <T2>COM2'</T2>
      <T3>COM2</T3>
   </NAME>
</ITEM>
<Call> 'COM2']</Call>
<vCountSeparators>0</vCountSeparators>
<ITEM>
   <NAME>
      <T1> 'COM2']</T1>
      <T2>COM2']</T2>
      <T3>COM2</T3>
   </NAME>
</ITEM>

Ich hoffe, das hat jetzt ein kleines bisschen geholfen.

Viele Grüße,

Konrad
 

RicoTT

Mitglied
Hallo Konrad,

vielen Dank für die ausführliche Antwort.
Im Laufe des gestrigen Tages war ich dann
auch alleine auf die Lösung gekommen.

Ein Problem habe ich jetzt noch.Die Einzulesende XML variert, das heißt
das Feld PropertyValue kann frei sein, oder 1-3 "COM" enthalten.
Angepasst daran sollen passend Items erstellt werden.

Also das wäre die Quelle:
Code:
<Property FormattingType="0" FormattingLength="32" FormattingRAlign="1">
<PropertyName>Zusatzfeld </PropertyName>
<PropertyValue>['COM1', 'COM2', 'COM3']</PropertyValue>
</Property>

<Property FormattingType="0" FormattingLength="32" FormattingRAlign="1">
<PropertyName>Zusatzfeld </PropertyName>
<PropertyValue>['COM1']</PropertyValue>
</Property>

<Property FormattingType="0" FormattingLength="32" FormattingRAlign="1">
<PropertyName>Zusatzfeld </PropertyName>
<PropertyValue>['COM1', 'COM2']</PropertyValue>
</Property>

Und daraus soll das hier entstehen:
Code:
<ITEM>
      <NAME>COM1</NAME>
</ITEM>
<ITEM>
      <NAME>COM2</NAME>
</ITEM>
<ITEM>
      <NAME>COM3</NAME>
</ITEM>
<ITEM>
      <NAME>COM1</NAME>
</ITEM>
<ITEM>
      <NAME>COM1</NAME>
</ITEM>
<ITEM>
      <NAME>COM2</NAME>
</ITEM>
 
K

kneitzel

Gast
Das hast Du doch eigentlich in meinem Transform schon. Die ganzen Zusatzausgaben entfernen und ggf. noch ein eigenes template zum Wert anzeigen und schon ist man fertig.

Einziges Problem: Deine Vorgabe ist kein gültiges XML - Du brauchst genau ein root Element. Das habe ich einfach einmal hinzugefügt als "items" (Properties wäre evtl. besser gewesen, aber ich habe es nicht noch einmal angepasst.):
Code:
<items>
<Property FormattingType="0" FormattingLength="32" FormattingRAlign="1">
<PropertyName>Zusatzfeld </PropertyName>
<PropertyValue>['COM1', 'COM2', 'COM3']</PropertyValue>
</Property>

<Property FormattingType="0" FormattingLength="32" FormattingRAlign="1">
<PropertyName>Zusatzfeld </PropertyName>
<PropertyValue>['COM1']</PropertyValue>
</Property>

<Property FormattingType="0" FormattingLength="32" FormattingRAlign="1">
<PropertyName>Zusatzfeld </PropertyName>
<PropertyValue>['COM1', 'COM2']</PropertyValue>
</Property>
</items>

Dann das xslt angepasst:
- im globalen Match muss dann der Ausdruck für die Property Elemente geändert werden. Das ist nun halt nicht mehr Property sondern items/Property
- Die Debug-Ausgaben entfernt
- das template ShowValues eingefügt, damit der Code zum Entfernen der Zeichen bis einschließlich des ' und danach ab dem ' nur noch an einer Stelle zu finden sind.
- template für den Split noch umbenannt (SplitValues statt SplitLinks)
Und damit haben wir dann folgendes xslt:
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
            <xsl:apply-templates select="items/Property"/>
    </xsl:template>

    <xsl:template match="Property">
        <xsl:call-template name="SplitValues">
            <xsl:with-param name="ComList" select="PropertyValue/text()"/>
        </xsl:call-template>
    </xsl:template>

    <!-- template to show value -->
    <xsl:template name="ShowValue">
        <xsl:param name="Value"/>
                    <xsl:variable name='t2' select='substring-after($Value,"&apos;")' />
                    <xsl:variable name='t3' select='substring-before($t2,"&apos;")' />
                    <xsl:value-of select="$t3"/>
    </xsl:template>

    <!-- recursive template for splitting links -->
    <xsl:template name="SplitValues">
        <xsl:param name="ComList"/>
        <xsl:variable name="vCountSeparators" select="string-length($ComList) - string-length(translate($ComList,',',''))"/>

        <xsl:choose>
            <xsl:when test="$vCountSeparators = 0">
              <ITEM>
                <NAME>
                   <xsl:call-template name="ShowValue">
                       <xsl:with-param name="Value" select="$ComList"/>
                   </xsl:call-template>
                </NAME>
              </ITEM>
            </xsl:when>

            <xsl:when test="$vCountSeparators &gt;= 1">
            <ITEM>
                <NAME>
                   <xsl:call-template name="ShowValue">
                       <xsl:with-param name="Value" select="substring-before($ComList,',')"/>
                   </xsl:call-template>
                </NAME>
            </ITEM>
                <!-- recursive call -->
                <xsl:call-template name="SplitValues">
                    <xsl:with-param name="ComList" select="substring-after($ComList,',')"/>
                </xsl:call-template>
            </xsl:when>

        </xsl:choose>

     </xsl:template>
</xsl:stylesheet>

Und damit erhält man dann tatsächlich:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<ITEM>
   <NAME>COM1</NAME>
</ITEM>
<ITEM>
   <NAME>COM2</NAME>
</ITEM>
<ITEM>
   <NAME>COM3</NAME>
</ITEM>
<ITEM>
   <NAME>COM1</NAME>
</ITEM>
<ITEM>
   <NAME>COM1</NAME>
</ITEM>
<ITEM>
   <NAME>COM2</NAME>
</ITEM>
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Sachinbhatt Python string find() examples XML & JSON 1
N JSON export String Unicode? XML & JSON 6
W Request als String XML & JSON 0
L Soapnachricht aus String erstellen XML & JSON 0
P Bestimmte XML-Inhalte in String lesen XML & JSON 2
M RSS als String speichern XML & JSON 12
W XMLStreamReader zu String machen? XML & JSON 2
B XML-Element als String ausgeben XML & JSON 5
H XML String auslesen XML & JSON 4
H XML String erstellen XML & JSON 4
T Wie einen String(XML Inhalt) in eine XML Datei speichern? XML & JSON 8
N XML-String in MIDP auslesen XML & JSON 3
W String nach XML nach String verwandeln XML & JSON 4
W XML DomDocument als String auslesen XML & JSON 2
B jdom document aus string erzeugen? XML & JSON 1
H Adapter: String->Element bzw. Element->String XML & JSON 6
A XML Tags als PHP String XML & JSON 4
S String in element casten XML & JSON 2
I XML-String mit SAX parsen ? XML & JSON 2
S JAVA XML Parser der einen String parst XML & JSON 3
G Elementbaum in String umwandeln XML & JSON 5
A StAX API: Cannot Cast from QName to String! XML & JSON 2
S org.jdom.document in String umwandeln. XML & JSON 2
S DefaultMutableTreeNodes als String in Textdatei speichern XML & JSON 7
W Xml-String parsen XML & JSON 2
B XML String einlesen XML & JSON 4
R XML Document als String XML & JSON 2
M Probleme mit String XML & JSON 3
G getAtributeValue liefert String mit störenden Steuerzeichen XML & JSON 2
D Text, String vor einem Root Element einfügen XML & JSON 2
R wie kann ich ein xml file in einen string einlesen? XML & JSON 2
E Element.setTextContent(String); Ersatz fuer Version 1.4? XML & JSON 3
W xslt zum Rausfiltern von Feldern in XML wenn variable gleich false XML & JSON 7
W xslt zum Entfernen von unnoetigen Nullkommastellen bei double und float XML & JSON 26
K XML und XSL bzw XSLT XML & JSON 1
R Script in XSLT einbinden XML & JSON 2
K aus 2XML mache 1XML mit XSLT XML & JSON 4
G xslt Attributwerte von bestimmten Elementen XML & JSON 2
S Xslt Problem XML & JSON 2
K docBook XSLT: HTML Code Snippet in Erzeugte HTML Dokument einfügen XML & JSON 9
T XML + XSLT to PDF mit FOP-Engine XML & JSON 14
E FOP - XSLT Transformierung mit Parametern XML & JSON 4
R '&' Zeichen im XSLT XML & JSON 4
S byte array in xslt umwandeln XML & JSON 7
B XSLT collections ? XML & JSON 2
Raidri JSP Parameter an XSLT übergeben XML & JSON 2
K XSLT Frage XML & JSON 4
S Guter XSLT - Transformator XML & JSON 2
slawaweis Problem mit XSLT (wahrscheinlich ein Bug in Java 6) XML & JSON 16
G XSLT-Stylesheet XML & JSON 2
N jdom - xslt-Verweis in .xml einfügen XML & JSON 3
B anzeigen des XML+ XSLT Ergebnisses XML & JSON 21
N XML zu XSLT XML & JSON 2
N XSLT Testmethoden XML & JSON 2
M Java und XSLT: Performanz-Problem XML & JSON 5
cybermat Ergebnis einer XSLT-Tansformation als Rückgabewert erhalten XML & JSON 4
A Wie hängen SAX/DOM mit XSLT zusammen? XML & JSON 3
Noar XSLT - Element-Wrapping XML & JSON 2
byte XSLT Transformation "ohne Server" XML & JSON 6
byte XSLT Editor ? XML & JSON 7
P XSLT in Java verwenden XML & JSON 7
A XSLT oder Java? / XML-Tools XML & JSON 2
T XSLT Parameter übergeben und Ergebnis empfangen XML & JSON 1

Ähnliche Java Themen

Neue Themen


Oben