[XSLT] missende elementen aanvullen?

Pagina: 1
Acties:

  • tazzman
  • Registratie: Juli 2000
  • Laatst online: 05-01 10:48

tazzman

a real boardmonkey

Topicstarter
Nou ben ik absoluut geen XML/XSD/XSLT guru ... so bear with me :)

Uit Systeem A ontvang ik XML bestanden met informatie over klanten. Wanneer iemand in dat systeem op "SAVE" drukt, vliegt er een XML bestand uit wat ik weer moet inlezen in een ander systeem.

Deze XML bestanden worden aangemaakt aan de hand van een XSD waarin 99% van de elementen OPTIONAL zijn, met MinOccurence 0 en Nullable is leeg. Het gevolg daarvan is dat ik in de output XML file alleen die elementen krijg welke gevuld zijn.

Ik krijg dus geen uniforme XML bestanden, elk bestand heeft meer of minder elementen - puur afhankelijk van de "vulling".

Aan de andere kant wordt een ETL gebruikt om al deze XML files in te lezen in een database. Deze tool gebruikt weliswaar hetzelfde XSD maar is helaas niet zo flexibel. De mappings van het ETL proces tussen de inkomende XML file en de tabellen in de database gaan hier problemen geven - omdat de input "column" soms wel en soms niet bestaat.

Nou was het mijn idee om dmv een XSLT transformatie die XML bestanden om te zetten in een XML bestand welke wel alle elementen bevat, ook al zijn ze leeg. Daarmee heb ik een vaste structuur waarmee de ETL tool wel overweg kan.

Dus heb ik een nieuwe XSD gemaakt waarin de MinOccurence van de elementen 1 is en Nillable is True. Met behulp van MapForce een XSLT aangemaakt door de oude XSD en de nieuwe XSD aan elkaar te koppelen..... en nou loop ik een beetje vast omdat ik niet echt weet hoe ik in de XSLT moet aangeven dat een missend element wel aangemaakt moet worden.

Wanneer ik de XSLT transformatie uitvoer (dmv nxslt bv) dan werkt alles prima, ik krijg een heel mooi nieuw xml bestand.. maar de ontbrekende elementen zijn niet opgenomen.

Iemand enig idee om mij hiermee een beetje op weg te helpen? :)

Het nieuwe speelgoed: een Saab 9-3 Aero (absoluut, helemaal en compleet fantastisch....)


  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
met xslt leg je vast HOE je om wilt gaan bij binnenkomende xml.
als er geen xml binnenkomt .. dan doet een standaard xslt-template helemaal niks (en dat merk je) :-)

als je extra xml wilt toevoegen bij nietbestaande nodes, dan kan je met count en xsl:if testen of er in de binnenkomende xml wel de nodes zitten die jij wilt, en evt extra xml printen naar de output.

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 20-02 03:31

Gerco

Professional Newbie

Een eenvoudige (maar wel arbeidsintensieve) manier om hiermee om te gaan is de XML transformeren naar "hetzelfde" formaat. Stel je hebt een XML waar de elementen a, b, c en d in moeten voorkomen, dan schrijf genereer je de volgende xslt:

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<xsl:stylesheet .... >
  <xsl:template match="/">
    <a>
      <xsl:value-of select="a"/>
    </a>
    <b>
      <xsl:value-of select="b"/>
    </b>
    <c>
      <xsl:value-of select="c"/>
    </c>
    <d>
      <xsl:value-of select="p"/>
    </d>
  </xsl:template>
</xsl:stylesheet>


Je zou ook een XSL kunnen maken die de .xsd en .xml als invoer heeft en daar alle ontbrekende velden inzet. Is iets ingewikkelder, maar wel beter future-proof dan dit. Hoe je dat zou moeten aanpakken weet ik zo even niet, maar als je alleen naar minOccurs kijkt, zal het wel redelijk meevallen.

[ Voor 42% gewijzigd door Gerco op 26-04-2006 15:43 . Reden: copy/paste errors verbeteren ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • tazzman
  • Registratie: Juli 2000
  • Laatst online: 05-01 10:48

tazzman

a real boardmonkey

Topicstarter
Ah, ik had zo'n vermoeden dat het allemaal niet zo makkelijk zou gaan als ik gehoopt had. :) Ik zal dus eigenlijk dmv een IF statement moeten controleren of een node/element bestaat en zo niet, dan deze toevoegen als een leeg element aan de output XML.

Helaas is het een draak van een XSD met behoorlijk veel elementen etc. Er is zeker geen manier omzoiets te generenen... het wordt echt ouderwets klopwerk? :)

Overigens alvast erg bedankt voor de input - het wordt enorm op prijs gesteld!

Het nieuwe speelgoed: een Saab 9-3 Aero (absoluut, helemaal en compleet fantastisch....)


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 20-02 03:31

Gerco

Professional Newbie

<xsl:if> is niet echt nodig, je zou een XSLT kunnen maken zoals ik hierboven voorstel. Je moet die dan natuurlijk wel wijzigen als de XSD wijzigt anders ga je je sterk zitten afvragen waar je data is gebleven die in dat extra veld stond.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • tazzman
  • Registratie: Juli 2000
  • Laatst online: 05-01 10:48

tazzman

a real boardmonkey

Topicstarter
Gerco schreef op woensdag 26 april 2006 @ 15:44:
<xsl:if> is niet echt nodig, je zou een XSLT kunnen maken zoals ik hierboven voorstel. Je moet die dan natuurlijk wel wijzigen als de XSD wijzigt anders ga je je sterk zitten afvragen waar je data is gebleven die in dat extra veld stond.
Dat werkt inderdaad goed, mijn huidige xslt werkt netjes alle elementen af dmv een "for-each" statement. Maar ja, wanneer er iets niet is, dan slaat hij dat natuurlijk netjes over besef ik me nu.

Dus die moeten er uit - maar stel je hebt een element genaamd "bank-rekening" onder "klant". Een klant kan 1/N bankrekeningen hebben. Wanneer ik daar "hard-coded" het bankrekening element in zet, zonder een "for-each" statement, worden de variabele bank-rekening elementen overgenomen? Of gaat daar iets fout?

Het nieuwe speelgoed: een Saab 9-3 Aero (absoluut, helemaal en compleet fantastisch....)


  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
iets meer advanced dan :)

je hebt een xml die 'standaard' is voor het geval xmlA leeg is.

met de volgende template kan je alles copieren van input naar output
code:
1
2
3
4
5
6
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*" />
         <xsl:apply-templates />
      </xsl:copy>
   </xsl:template>


nu is het plan dat er steeds even wordt gekeken per node of er misschien iets is in xmlA die de voorkeur geniet boven de standaard xml.

ik zit me nog even te beraden of je het kan, en hoe je dat nou het beste zou kunnen doen.

--edit: ik had niet gezien dat je al een richting had .. sry ..

[ Voor 13% gewijzigd door joopst op 26-04-2006 16:10 ]


  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
check deze eens, die heeft volgens mij wat jij zoekt :)

  • tazzman
  • Registratie: Juli 2000
  • Laatst online: 05-01 10:48

tazzman

a real boardmonkey

Topicstarter
Opzich ben ik er wel uit hoe ik het zou kunnen doen.

Door eerst te testen of een bepaald element bestaat. Zo ja, dan doen we een for-each transformation voor elk element. Maar zo niet, dan voegen we een leeg element toe.

Enige probleem is, dat is nogal een werkje om te typen... en de XSD is groot... heel, heel erg groot. :/

Het nieuwe speelgoed: een Saab 9-3 Aero (absoluut, helemaal en compleet fantastisch....)


  • tazzman
  • Registratie: Juli 2000
  • Laatst online: 05-01 10:48

tazzman

a real boardmonkey

Topicstarter
Zou het misschien een snellere methode te zijn om een "ideale en complete" lege XML file te genereren en deze te mergen met de inkomende XML file?

Het nieuwe speelgoed: een Saab 9-3 Aero (absoluut, helemaal en compleet fantastisch....)

Pagina: 1