xslt transformacija

Prosil bi, če mi pomagate:

imam xml iz tujine, ki ga hočem transformirat v naš standardni xml format. Notri je tudi za vsak item vrstica:
<PropertyDescriptions>
<PropertyDescription>
<DescriptionText>....OPIS ......</DescriptionText>
<DescriptionType DescriptionType="4" />
</PropertyDescription>
<PropertyDescription>
<DescriptionText>2 SOBNO STANOVANJE NA TABORU</DescriptionText>
<DescriptionType DescriptionType="6" />
</PropertyDescription>
</PropertyDescriptions>

rad bi dobil sledeč izpis:

<table6>2 SOBNO STANOVANJE NA TABORU</table6>
<table4>....OPIS....<table>

Poizkusil sem že na 2 načina:
1)
<xsl:template match="PropertyDescriptions/PropertyDescription">
<xsl:for-each select="DescriptionType">
<xsl:element name="Title{@DescriptionType}"><xsl:value-of select="DescriptionText" />
/xsl:element
/xsl:for-each/xsl:template

in <xsl:apply-templates select="PropertyDescriptions/PropertyDescription" />
rezultat je :
<Table4/>
<Table6/>

če pa probam takole:

<xsl:template match="PropertyDescriptions/PropertyDescription">
<xsl:for-each select=".">
<xsl:element name="table{@DescriptionType}"><xsl:value-of select="DescriptionText" />
/xsl:element
/xsl:for-each/xsl:template

pa je rezultat:

<table>2 SOBNO STANOVANJE NA TABORU</table>
<table>....OPIS....</table>

Prosim, če mi pomagate, da dobim pravilni izpis tagov

3 odgovori

Problema sta dva.

Problem št. 1: Pri prvi kodi je problem v tem, da loop-aš po DescriptionType namesto po PropertyDescription. Ker potem DescriptionText ni child od DescriptionType-a, ti vrne prazno vrednost za DescriptionText. Kar ti pri drugi varianti sicer uspe, ampak potem se pa znajdeš pred 2. problemom.

Problem št. 2: je pa v tem, da je XML naravnost debilen. Problem je v DescriptionType-u. Če je že avtor XML-ja hotel izpostaviti tip opisa, potem bi ga lahko navedel kot atribut (xml varianta 1):

<PropertyDescription DescriptionType="4">
    <DescriptionText>...</DescriptionText>
</PropertyDescription>

ali pa kot polje (xml varianta 2):

<PropertyDescription>
    <DescriptionText>...</DescriptionText>
    <DescriptionType>4</DescriptionType>
</PropertyDescription>

ali konec koncev vse skupaj precej krajše (brez DescriptionText) takole:

<PropertyDescription DescriptionType="4">...</PropertyDescription>

Predlagam ti, da s kakim editorjem in uporabo search/replace popraviš vrstice z DescriptionType iz

<PropertyDescription DescriptionType="4">...</PropertyDescription>

v

<DescriptionType>4</DescriptionType>

V tem primeru (glej xml varianta 2) bo XSLT koda za izpis naslednja:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="PropertyDescriptions">
    <xsl:for-each select="PropertyDescription">
        <xsl:element name="table{DescriptionType}">
            <xsl:value-of select="DescriptionText" />
        </xsl:element>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Izvirni greh je torej XMLju "iz tujine" (Saturn, Jupiter?) in ne toliko v "domačem" XSLTju... :)

4

Hvala @Perro, ampak ali mi lahko pomagaš, da obstoječega spremenim v željeno?

Partner iz tujine, ki pošilja svoj xml je tako nefleksibilen in vztraja pri svojem.

Kot sem že omenil v prejšnjem postu, spremeni vse vrstice tipa

<DescriptionType DescriptionType="4"/>

v

<DescriptionType>4</DescriptionType>

Kako to narediš (razen na roke). Če si na Linuxu ali Mac OS, potem izvedi naslednje:

$ cat datoteka.xml |
sed -e 's; DescriptionType="\([0-9]\)*" />;>\1</DescriptionType>;g'

Ukaz sed ti s pomočjo regularnih izrazov (RE) zamenja tisti atribut v željeno obliko (xml varianta 2 iz prejšnjega posta).

Če si na Windows, instaliraj Linux... :) Lahko naložiš CygWin, nek približek Linuxa za na Windowse. Še bolje, zalaufaj kak Linux Live CD in naredi samo to, in shrani rezultat na kak ključek. Sicer obstaja nek urejevalnik UltraEdit, ki ima možnost uporabe regularnih izrazov pri opearciji serach/replace. Kako boš pa prevedel klobaso iz sed-a v UltraEdit, je pa že drugo vprašanje. Tudi nisem prepričan, da bo vse skupaj delovalo.

Sej vem, da izgledajo zoprno, ampak RE so res eno močno orodje za premetavanje v takih situacijah. No, ko bo vse to za teboj, pa uporabi XSLT s konca prejšnjega posta.

2