Announcement

Collapse
No announcement yet.

Brauche Hilfe bei XML Umstrukturierung

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

  • Brauche Hilfe bei XML Umstrukturierung

    Hi,

    ich habe eine XML Datei, die syntaktisch wie folgt strukturiert ist (siehe erste Code Box).
    Da dieses Format eine schiere Katastrophe für Parsing darstellt, muss ich es umstrukturieren. Leider habe ich nicht im geringsten ausreichend Ahnung in XSL, um das selbst auf die Reihe zu bekommen. (Zumal ich sonst quasi nie mit XML, geschweige denn XSL direkt zu tun habe.) XSL dieser komplexität ("following-sibling:", etc) sind leider noch bömische Dörfer.
    Und mir reicht die Zeit nicht, um mir für diese eine Situation XSL zu 100% selbst beizubringen, daher hoffe ich auf einen hilfsbereiten Helfer hier. Ich weiß, "hey guys, please, write my code"-Posts sind nicht sehr beliebt unter Devs (bin ja schießlich selbst einer ), aber mir bleibt hier leider nichts anderes übrig. Habe schon viel zu viel Zeit damit verbracht zu versuchen die Sache mit SAX parsing zu erledigen. War eine riesige P.I.T.A und am Schluss viel zu buggy und slow.

    Ich hoffe jemand kann mir aus der Patsche helfen.

    Vielen, vielen Dank im Voraus.

    So sieht's aus (Sample aller in "Plist"-XML erlaubten Elemente):
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>nameOfDict</key>
    	<dict>
    		<key>nameOfArray</key>
    		<array>
    			<string>F</string>
    			<integer>0</integer>
    			<integer>0</integer>
    			<string>bar</string>
    		</array>
    		<key>nameOfBooleanFalse</key>
    		<false/>
    		<key>nameOfBooleanTrue</key>
    		<true/>
    		<key>nameOfData</key>
    		<data>
    		/wD/AP8A/wA=
    		</data>
    		<key>nameOfDate</key>
    		<date>2008-11-04T23:00:00Z</date>
    	</dict>
    	<key>nameOfNumber</key>
    	<integer>42</integer>
    	<key>nameOfString</key>
    	<string>Foobar</string>
    </dict>
    </plist>
    So brauche ich es:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <dict>
    	<dict key="nameOfDict">
    		<array key="nameOfArray">
    			<string key="0">F</string>
    			<integer key="1">0</integer>
    			<integer key="2">0</integer>
    			<string key="3">bar</string>
    		</array>
    		<bool key="nameOfBooleanFalse">false</bool>
    		<bool key="nameOfBooleanTrue">true</bool>
    		<data key="nameOfData">
    		/wD/AP8A/wA=
    		</data>
    		<date key="nameOfDate">2008-11-04T23:00:00Z</date>
    	</dict>
    	<integer key="nameOfNumber">42</integer>
    	<string key="nameOfString">Foobar</string>
    </dict>
    Konkret lassen sich die Änderungen wie folgt beschreiben:
    1. Keys in nachfolgendes Element als Attribut integrieren.
    2. Kinder eines Arrays im "key"-Attribut durchnummieren (hoffe sehr, dass das geht).
    3. "</true>" oder "</false>" zu <bool>…</bool> abändern.

    Achja, nochwas: der Output muss keine Formattierung (Einrückungen & Zeilenumbrüche) haben. (wäre sogar besser ohne sie)

    Hier sind zwei XSL Samples, die ich hab finden können, die sehr ähnliches machen, falls es hilft.
    http://blog.traditionalcake.org/2007...erty-list.html
    http://www.xmldatabases.org/WK/blog/1086?t=item
    --
    http://www.vic-fontaine.com/

  • #2
    Hier mal ein Ansatz, der sich ggf. noch optimieren lässt:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
    
      <xsl:template match="plist">
        <xsl:apply-templates select="dict"/>
      </xsl:template>
    
      <xsl:template match="dict">
        <dict>
          <xsl:if test="preceding-sibling::key">
            <xsl:attribute name="key">
              <xsl:value-of select="preceding-sibling::key"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:apply-templates/>
        </dict>
      </xsl:template>
    
      <xsl:template match="array">
        <array>
          <xsl:attribute name="key">
            <xsl:value-of select="preceding-sibling::key"/>
          </xsl:attribute>
    
          <xsl:for-each select="string | integer">
            <xsl:element name="{name()}">
              <xsl:attribute name="key">
                <xsl:value-of select="position() - 1"/>
              </xsl:attribute>
              <xsl:value-of select="normalize-space(.)"/>
            </xsl:element>
          </xsl:for-each>
        </array>
      </xsl:template>
    
      <xsl:template match="false | true">
        <bool key="{preceding-sibling::key[1]}">
          <xsl:value-of select="name()"/>
        </bool>
      </xsl:template>
    
      <xsl:template match="data | date | string | integer">
        <xsl:element name="{name()}">
          <xsl:attribute name="key">
            <xsl:value-of select="preceding-sibling::key[1]"/>
          </xsl:attribute>
          <xsl:value-of select="normalize-space(.)"/>
        </xsl:element>
      </xsl:template>
    
      <xsl:template match="key | text()"/>
    
    </xsl:stylesheet>

    Comment

    Working...
    X