XML mittels XSLT in Java Properties umwandeln

Fenrizwolf

Grünschnabel
Hallo!

Ich stehe gerade vor einem Problem. Ich muss eine beliebige XML Struktur auf Java Properties mappen.

Dh ich habe ein XML das zB so aussieht:
xml Code:
<cfg>

<a>

<b attr="hello"/>

</a>

</cfg>



und das ganze soll dann mittels XSLT in die folgende Form gebracht werden.

xml Code:
<properties>

<entry key="cfg.a.b.attr">hello</entry>

</properties>




Leider habe ich grad keine Idee wie ich mir das key Attribute für die Java Properties vollständig zusammen bauen kann. Wäre sehr nett wenn mir jemand weiterhelfen könnte, da ich dafür so schnell wie möglich eine Lösung brauchen würde.


Lg und vielen Dank im Vorraus,

Fenrizwolf
 
Hi!

Ich hab' zwar keine Ahnung von Java Properties, aber mit deinem Beispiel kommt der Code hier prima klar:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="xml" encoding="UTF-8"/>

  <xsl:template match="/">
   <properties>
    <xsl:call-template name="recurse"/>
   </properties>
  </xsl:template>

  <xsl:template name="recurse">
   <xsl:param name="depth"/>
   <xsl:choose>
    <xsl:when test="count(./attribute::*)">
     <xsl:for-each select="./attribute::*">
      <entry>
       <xsl:attribute name="key">
        <xsl:value-of select="concat($depth, local-name())"/>
       </xsl:attribute>
       <xsl:value-of select="string()"/>
      </entry>
     </xsl:for-each>
    </xsl:when>
    <xsl:otherwise>
     <xsl:for-each select="./child::*">
      <xsl:call-template name="recurse">
       <xsl:with-param name="depth" select="concat($depth, local-name(), '.')"/>
      </xsl:call-template>
     </xsl:for-each>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

Gruß
Enum
 
Hallo!
Dieses Problem ist nun gelöst - aber somit stehe ich auch schon wieder vor dem nächsten Problem.
Gibt es auch eine Möglichkeit den umgekehrten Weg zu gehn, dh aus den Java Properties eine beliebige XML Struktur (siehe erster Post) mittels XSLT zu generieren.

Vielen Dank im Vorraus!

Lg,
Fenrizwolf
 
Hi!

Du kannst also offensichtlich XSLT und XPath in der Version 2.0+ benutzen. Das ist Dein Glück, mit den Vorgängern wäre das ein RIESEN-Aufwand, vor allem wenn man berücksichtigen will, dass Schlüssel wie "cfg.a.b.attr" und "cfg.a.c.attr" auch vorkommen können, in einem Dokument.
Allerdings hab' ich nicht so viel Ahnung von den 2er Versionen und glaub' nicht dass ich da eine große Hilfe wär'...

Gruß
Enum

[EDIT]
Soo, das wäre meine Lösung in XSL-T 2 - geht aber garantiert noch besser:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" encoding="UTF-8"/>

  <xsl:template match="/properties">
   <xsl:variable name="root" select="substring-before(./entry[1]/@key, '.')"/>
   <xsl:element name="{$root}">
    <xsl:call-template name="recurse">
     <xsl:with-param name="prefix" select="$root"/>
    </xsl:call-template>
   </xsl:element>
  </xsl:template>

  <xsl:template name="recurse">
   <xsl:param name="prefix"/>
   <xsl:for-each-group select="./entry[starts-with(@key, $prefix)]"
       group-by="substring-before(substring-after(@key, concat($prefix, '.')), '.')">
    <xsl:variable name="area"
        select="substring-before(substring-after(@key, concat($prefix, '.')), '.')"/>
    <xsl:variable name="remain"
        select="substring-after(@key, concat($prefix, '.', $area, '.'))"/>
    <xsl:choose>
     <xsl:when test="contains($remain, '.')">
      <xsl:element name="{$area}">
       <xsl:variable name="new_prefix" select="concat($prefix, '.', $area)"/>
       <xsl:for-each select="/properties">
        <xsl:call-template name="recurse">
         <xsl:with-param name="prefix" select="$new_prefix"/>
        </xsl:call-template>
       </xsl:for-each>
      </xsl:element>
     </xsl:when>
     <xsl:otherwise>
      <xsl:for-each select="current-group()">
       <xsl:element name="{$area}">
        <xsl:attribute name="{$remain}">
         <xsl:value-of select="string(.)"/>
        </xsl:attribute>
       </xsl:element>
      </xsl:for-each>
     </xsl:otherwise>
    </xsl:choose>
   </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück