Nummer zusammen bauen
Mathias
- xsl
Hallo,
habe ein verschachteltes XML (siehe Beispiel 1) und möchte es in eine flache Struktur bingen (siehe Beispiel 2). Klappt soweit bis auf die Teilenummer. In der Ursprungs-Datei ist die Teilenummer auf die Hierachieebene aufgesplittet. Im Ziel-XMl sollen muss sie wieder komplett sein. Bin XSL-Anfänger und konnte bisher im Internet nichts vergleichbares finden, was mir weitergeholfen hätte. Bin für jeden Gedankenanreiz dankbar!
P.S.: Nein - die Teilenummer steht nicht wie hier im Beispiel im <infos>-Tag. Ist nur der besseren Übersicht wegen... Sie steht nur als Attribut unter Teil.
<text>abc</text>
<teil nr="1">
<infos>infos zu teil 1</infos>
<text>abc</text>
<teil nr="10">
<infos>infos zu teil 1.10</infos>
<text>abc</text>
<teil nr="10">
<infos>infos zu teil 1.10.10</infos>
</teil>
</teil>
<teil nr="20">
<infos>infos zu teil 1.20</infos>
</teil>
</teil>
<teil nr="2">
<infos>infos zu teil 2</infos>
</teil>
<text>abc</text>
<teil nr="3">
<infos>infos zu teil 3</infos>
<teil nr="10">
<infos>infos zu teil 3.10</infos>
</teil>
</teil>
<teil>
<text>abc</text>
<nr>1</nr>
<infos>infos</infos>
</teil>
<teil>
<text>abc</text>
<nr>1.10</nr>
<infos>infos</infos>
</teil>
<teil>
<text>abc</text>
<nr>1.10.10</nr>
<infos>infos</infos>
</teil>
<teil>
<nr>1.20</nr>
<infos>infos</infos>
</teil>
<teil>
<nr>2</nr>
<infos>infos</infos>
</teil>
<teil>
<text>abc</text>
<nr>3</nr>
<infos>infos</infos>
</teil>
<teil>
<nr>3.10</nr>
<infos>infos</infos>
</teil>
Mathias
Tach Mathias,
Bin XSL-Anfänger und konnte bisher im Internet nichts vergleichbares finden, was mir weitergeholfen hätte. Bin für jeden Gedankenanreiz dankbar!
Das folgende Stylesheet verarbeitet alle teil-Elemente im Dokument:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1"/>
<xsl:template match="/">
<teile_neu>
<xsl:apply-templates select="//teil"/>
</teile_neu>
</xsl:template>
<xsl:template match="teil">
<teil>
<text><xsl:value-of select="text"/></text>
<nr><xsl:value-of select="@nr"/></nr>
<infos><xsl:value-of select="infos"/></infos>
</teil>
</xsl:template>
</xsl:stylesheet>
Man liest sich,
svg4you
Hi svg4you,
Danke für dein Antwort, das ist aber nicht das was ich meinte [ das hätte ich auch noch hinbekommen ;-)]. Vielleicht hab ich mit etwas zu umständlich ausgedrückt:
das Problem ist nicht einfach das Attribut Nr auszulesen, sondern das Zusammenbauen der neuen Nr, welche aus den einzelnen Attributen Nr der vorigen Ebene besteht:
<teil1 Nr1/> 1. Ebene
<teil2 Nr10/> 2. Ebene
<teil3 Nr10/> 3. Ebene
<teil4 Nr20> 2. Ebene
<teil5 Nr2> 1. Ebene
<teil6 Nr3> 1. Ebene
<teil7 Nr10/> 2. Ebene
<teil8 Nr20/> 2. Ebene
<teil_neu nr1 />
<teil_neu nr1.10 />
<teil_neu nr1.10.10 />
<teil_neu nr1.10.20 />
<teil_neu nr2 />
<teil_neu nr3 />
<teil_neu nr3.10 />
<teil_neu nr3.20 />
BoQCtgy sind die Teile. RNoPart ist die Teilenummer. In der letzten Hierarchieebene BoQCtgy=Item. Insgesamt können es bis zu 7 Hierarchiestufen sein.
<?xml version="1.0" encoding="UTF-8" ?>
Soll ergeben:
<Teil Nr 1/>
<Teil Nr 1.10/>
<Teil Nr 1.10.10/>
<Teil Nr 1.10.10.10/>
<Teil Nr 1.10.10.20/>
Tach Mathias,
das Problem ist nicht einfach das Attribut Nr auszulesen, sondern das Zusammenbauen der neuen Nr, welche aus den einzelnen Attributen Nr der vorigen Ebene besteht:
Liefere mal wohlgeformten XML-Daten, dann schaue ich nochmal drüber.
Man liest sich,
svg4you
Hi svg4you,
hier das wohlgeformte XML
<?xml version="1.0" encoding="UTF-8" ?>
<GAEB>
<GAEBInfo/>
<PrjInfo/>
<Award>
<AwardInfo/>
<BoQ>
<BoQBody>
<Remark/>
<BoQCtgy RNoPart="1">
<LblTx/>
<BoQBody>
<BoQCtgy RNoPart="10">
<LblTx/>
<BoQBody>
<BoQCtgy RNoPart="10">
<BoQBody>
<Itemlist>
<Item ID="BPNABIDI" RNoPart="10"/>
<Item ID="BPNABNFI" RNoPart="20"/>
</Itemlist>
</BoQBody>
</BoQCtgy>
</BoQBody>
</BoQCtgy>
</BoQBody>
</BoQCtgy>
</BoQBody>
</BoQ>
</Award>
</GAEB>
Falls es interessiert, hier gibt's ein etwas größerers Beispiel:
http://www.gaeb-da-xml.de/content/version30/Musterdateien/2004-001.X81
Vielen Dank für deine Mühe.
Cheers Mathias
Tach Mathias,
hier das wohlgeformte XML
...
Mit diesem Ansatz
<xsl:template match="/">
<teile_neu>
<xsl:apply-templates select="//BoQCtgy"/>
</teile_neu>
</xsl:template>
<xsl:template match="BoQCtgy">
<xsl:variable name="nr">
<xsl:for-each select="ancestor-or-self::BoQCtgy">
<xsl:value-of select="@RNoPart"/>
<xsl:if test="position() != last()"><xsl:text>.</xsl:text></xsl:if>
</xsl:for-each>
</xsl:variable>
<teil nr="{$nr}"/>
</xsl:template>
komme ich bis zu
<?xml version="1.0" encoding="ISO-8859-1"?>
<teile_neu>
<teil nr="1"/>
<teil nr="1.10"/>
<teil nr="1.10.10"/>
</teile_neu>
Da müssten wohl noch die Bezüge zu BoQBody und Itemlist/Item hinein.
Man liest sich,
svg4you
Hi svg4you,
Funktioniert bei mir! War auf nem ganz anderen Weg, der aber leider nicht geklappt hat. Habe deinen Vorschlag nun benutzt:
<xsl:template match="BoQBody">
<xsl:call-template name="pos_tree_in">
</xsl:call-template>
</xsl:template>
<xsl:template name="pos_tree_in">
<xsl:if test="BoQCtgy">
<xsl:for-each select="BoQCtgy">
<ENTITY>
<xsl:if test="name(preceding-sibling::*[1]) = 'Remark'">
<LANG><xsl:value-of select="preceding-sibling::*[1]/Description/CompleteText/DetailTxt/Text"/></LANG>
<KURZ><xsl:value-of select="preceding-sibling::*[1]/Description/CompleteText/OutlineText/OutlTxt/TextOutlTxt"/></KURZ>
</xsl:if>
<xsl:variable name="nr">
<xsl:for-each select="ancestor-or-self::BoQCtgy">
<xsl:value-of select="@RNoPart"/>
<xsl:if test="position() != last()">xsl:text.</xsl:text></xsl:if> </xsl:for-each>
</xsl:variable>
<NUMB><xsl:value-of select="$nr" /></NUMB> <LBLTX><xsl:value-of select="LblTx"/></LBLTX>
<ITEM>No</ITEM>
</ENTITY>
<xsl:apply-templates select="BoQBody"/>
</xsl:for-each>
</xsl:if>
<xsl:if test="Itemlist">
<xsl:for-each select="Itemlist/Item">
<ENTITY>
<xsl:variable name="nr">
<xsl:for-each select="ancestor::BoQCtgy">
<xsl:value-of select="@RNoPart"/>
<xsl:if test="position() != last()">xsl:text.</xsl:text></xsl:if>
</xsl:for-each>
<xsl:if test="ancestor::BoQCtgys">xsl:text.</xsl:text></xsl:if>
<xsl:for-each select="ancestor-or-self::Item">
<xsl:value-of select="@RNoPart"/>
<xsl:if test="position() != last()">xsl:text.</xsl:text></xsl:if>
</xsl:for-each>
</xsl:variable>
<NUMB><xsl:value-of select="$nr" /></NUMB>
<LBLTX><xsl:value-of select="LblTx"/></LBLTX>
<ITEM>Yes</ITEM>
<QTY><xsl:value-of select="Qty"/></QTY>
<PREDOTY><xsl:value-of select="PredQty"/></PREDOTY>
<QU><xsl:value-of select="QU"/></QU>
</ENTITY>
</xsl:for-each>
</xsl:if>
</xsl:template>
Bestimmt könnte ich die Prüfung auf BoQCtgy und Item noch etwas eleganter umsetzen, abr ich bin nur froh das es funktioniert.
Vielen vielen Dank!!!!!
Grüße
Mathias