Announcement

Collapse
No announcement yet.

Multiple result-documents from multiple sources

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

  • Multiple result-documents from multiple sources

    Hi!

    I'm really new in XSLT, so excuse me, if my questions are trivial, but i've checked nearly the whole web, and couldn't find anything that matches for my problem!

    THE PROBLEM:
    I have to process a couple of source-XML-documents, which contains sensor-data. This should happen through an XSLT 2.0 stylesheet, called from console with SAXON, for the whole directory in which they are saved.

    The clou is, i have to use another XML source document, which is a fix template and have to be copied exactly to my result document AND i have to copy one sensor-data file at a time to that template in process, to a defined position (between a <text>...</text> element)!

    So, the result XML file must be the exact copy of the source template + change one node, that is, copy one sensor-data source file into it. So far so good. If i select only one sensor file, hard coded in the stylesheet, it works fine!

    What i want now is to process a whole directory of sensor files, one file after another and get one result-document for each template+sensorfile!
    That should happen with one stylesheet!


    QUESTION 1:
    Is that even possible with XSLT 2.0???

    QUESTION 2:
    The fn:collection(iri-to-uri('../DIR/DIR/?select=*.(xml)')) function should give me all files in that directory, but how can i walk through the items of the collection() and process them, one after another???

    QUESTION 3:
    Is there any for-loop in XSLT 2.0 or any other possibility like: for("all files in directory") do "somethin"? Maybe with <xsl:for-each "file"> element, BUT HOW?...doesn't work. Or is the only way recursion???

    QUESTION 4:
    XQuery isn't working inside an XSLT-stylesheet, right? Like: {for...let...where...return...}?

    I've tried so much, but all what i've reached is to copy the template complete in the result document, but can't identify the <text>-node and can't walk through the fn:collection() of source-files to copy them!!!

    Any suggestions? Please help me!!!

  • #2
    The fn:collection(...) syntax depends on the XSLT processor. AltovaXML can copy the contents of a set of XML documents in this way:
    Code:
    <xsl:copy-of select="for $doc in fn:collection('C:\Temp\*.xml') return $doc/whatever"/>
    You can use a subset of XQuery expression syntax in XSLT/XPath 2.0 (for ... in ... return, if ... then ... else, some/every ... in ... satisfies). See more features in this (german) presentation, at least the code fragments should be readable for you.

    Comment


    • #3
      Hi!

      Danke für die Antwort und die Präsentation!
      Ich hatte vergessen, dass ich in einem deutschen Forum bin!

      Leider bin ich auch mit den Code-Beispielen aus den Folien nicht viel weiter gekommen.

      Was ich bekomme sind mehrere Ergebnisdokumente mit dem jeweils korrekten Namen, den ich mir in der Variablen 'resultFileName' zusammenfüge.
      Die Quelldatei ist mein 'cdaTemplateFile', dieses wird auch in der Kommandozeile übergeben. Die zu verarbeitenden Dateien kommen aus der 'sensorFileCollection'.
      Ich versuche nun mein Quelldokument zu durchlaufen und jeden Knoten 1-zu-1 zu kopieren, solange er nicht 'text' heißt. Ist das der fall soll der inhalt jeweils einer Sensor-Datei in dieses Element kopiert werden. Das ganze einmal für jede Datei im Verzeichnis, also für jede Datei in der 'sensorFileCollection', so dass ich zum Schluss für jede Datei X im Verzeichnis erhalte: Template + <text>SensorDatei-X</text> + TemplateRest

      Ich versuche es mit einem <xsl:choose><xsl:when> Konstrukt, allerdings wird immer nur die erste when-Anweisung ausgewertet, die 2. nicht mehr. Als Ergebnis bekomme ich so entweder nur mein Quell-Template kopiert, oder wenn ich die when-Anweisungen in der Reihenfolge tausche, die Sensor-Datei in das Ergebnisdokument kopiert! WIESO NICHT BEIDE?!?

      Ich verzweifle hier!
      Hat vielleicht jemand eine Idee?

      Vielleicht hilft mein Quellcode weiter:
      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <?xml-stylesheet type="text/xsl" href="../../CDA.xsl"?>
      <xsl:stylesheet version="2.0" 
      						xmlns="urn:hl7-org:v3"
      						xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      						xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      						xmlns:fn="http://www.w3.org/2005/xpath-functions"
      						xmlns:cda="urn:hl7-org:v3"
      						xmlns:saxon="http://icl.com/saxon"  
      					   extension-element-prefixes="saxon" >
      
      	<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
      	
      	<xsl:variable name="cdaTemplateFile" select="document('../../CDA/template_Level2_CDA_structuredBody.xml')"/>
      	<xsl:variable name="sensorFileCollection" select="collection(iri-to-uri('../../AWK/?select=*.(xml)'))"/>
      
      	<xsl:template match="/">
      		<xsl:for-each select="$sensorFileCollection">
      			<xsl:variable name="currentFile" select="current()"/>
      			<xsl:variable name="sensorFileName" select="tokenize(document-uri(.), '[\\/]')[last()]"/>
      			<xsl:variable name="resultFileName" select="concat('CDA_', position(), '_', $sensorFileName)" />
      			
      				<xsl:result-document href="{$resultFileName}">
      					<xsl:choose>
      						<xsl:when test="$cdaTemplateFile/node()[local-name()='text']">
      							<xsl:copy>
      								<xsl:apply-templates select="@* | node()" />
      							</xsl:copy>
      						</xsl:when>
      
      						<xsl:when test="$cdaTemplateFile/node()[local-name()!='text'] ">
      							<xsl:copy>
      								<xsl:apply-templates select="$cdaTemplateFile[@*] | $cdaTemplateFile/node()" />
      							</xsl:copy>
      						</xsl:when>
      
      						<xsl:otherwise>
      							No match for 'text' !!!
      						</xsl:otherwise>
      					</xsl:choose>
      			</xsl:result-document>
      		</xsl:for-each>
      	</xsl:template>
      
      
      	<xsl:template match="@* | node()">
      		<xsl:copy>
      			<xsl:apply-templates select="@* | node()" />
      		</xsl:copy>
      	</xsl:template> 
      
      </xsl:stylesheet>

      Wäre um jede Hilfe dankbar!!

      Comment


      • #4
        xsl:choose | xsl:when ... xsl:when ... | xsltherwise funktionieren nach dem if | elseif ... elseif | else-Prinzip anderer Programmiersprachen. Verwende alternativ mehrere einzelne xsl:if-Statements, welche unabhängig voneinander sind.

        Comment


        • #5
          Ja, das habe ich auch nachlesen können.

          Mit <xsl:if> komme ich seltsamerweise auch nicht zum gewünschten Ergebnis!

          Dann erhalte ich zwar Template+Sensordaten in einem Ergebnisdokument, aber die Sensordaten, die ich innerhalb des <text>...</text> einfügen möchte
          werden hinter dem komplett kopierten Quell-Template eingefügt.

          Ist meine Adressierung des <text>-Elementes in der if-abfrage falsch???
          Ich versteh´s nicht!

          Die Quelldatei sieht vereinfacht dargestellt so aus:

          Code:
          	
          <ClinicalDocument>
             <component>
                <structuredBody>
          	 <component>
          	   <section>
          	      <component>
          	         <section>
                              <text>
          <!-- 
          ****************************************
          	Hier die Sensordaten eingefüen !!!
          **************************************
          -->
                 </text>
                </section>
               </component>
              </section>    
             </component>
            </structuredBody>
           </component>
          </ClinicalDocument>
          Das Stylesheet habe ich jetzt so umgeschrieben:

          Code:
          		
          <xsl:variable name="cdaTemplateFile" select="document('../../CDA/template_Level2_CDA_structuredBody.xml')"/>
          <xsl:variable name="sensorFileCollection" select="collection(iri-to-uri('../../AWK/?select=*.(xml)'))"/>
          
          <xsl:template match="/">
          	<xsl:for-each select="$sensorFileCollection">
          		<xsl:variable name="currentFile" select="current()"/>
          		<xsl:variable name="sensorFileName" select="tokenize(document-uri(.), '[\\/]')[last()]"/>
          		<xsl:variable name="resultFileName" select="concat('CDA_', position(), '_', $sensorFileName)" />
          			
          		<xsl:result-document href="{$resultFileName}">
          			<xsl:if test="$cdaTemplateFile//*[local-name()!='text']">
          				<xsl:copy>
          					<xsl:apply-templates select="$cdaTemplateFile[@*] | $cdaTemplateFile/node()" />
          				</xsl:copy>
          			</xsl:if>
          								
          			<xsl:if test="$cdaTemplateFile//*[local-name()='text']">
          				<xsl:call-template name="text">
          					<xsl:with-param name="currentFile" select="$currentFile"/>
          				</xsl:call-template>
          			</xsl:if>
          
          		</xsl:result-document>
          	</xsl:for-each>
          </xsl:template>
          
          <xsl:template name="text">
          	<xsl:param name="currentFile"/>
          	<xsl:copy-of select="$currentFile"/>
          </xsl:template>
          
          <xsl:template match="@* | node()">
          	<xsl:copy>
          		<xsl:apply-templates select="@* | node()" />
          	</xsl:copy>
          </xsl:template>

          Wo liegt denn wohl der Fehler???

          Comment


          • #6
            Das ist schwierig zu beurteilen ohne detaillierte Kenntnis aller Dokumente. Ich vermute, dass sich das Identitäts-Template und die anderen Templates in die Quere kommen. Vielleicht hilft es, diese text-Elemente beim Identitäts-Template auszulassen:
            Code:
            <xsl:template match="@* | node()[local-name() != 'text']">
            <!-- ... -->
            </xsl:template>

            Comment


            • #7
              Das könnte schon sein, dass sich die Templates in die Quere kommen.

              Allerdings habe ich grad eben festgestellt, dass im meiner letzten Templateregel:
              Code:
              <xsl:template xmlns:cda="urn:hl7-org:v3" match="cda:text">
                <xsl:param name="currentFile"/>
              	testtesttesttesttesttesttesttesttesttesttesttesttesttesttest
                  <xsl:copy-of select="$currentFile"/>
                    <xsl:apply-templates select="node()" />
              </xsl:template>
              ...der Parameter "currentFile" (welcher mir die aktuell zu verarbeitende Sensor-Datei übergeben soll) nicht bekannt ist!!

              Wenn ich z.B. <xsl:value-of select="$currentFile"/> im <xsl:result-document> aufrufe bekomme ich die Daten der aktuellen Sensordatei in jeweils ein korrekt benanntes Ergebnisdokument geschrieben.
              In dieser Template-Regel bekomme ich nur meinen Text-String "testtesttesttest" ausgegeben. das <xsl:copy-of select="$currentFile"/> wird nicht behandelt!

              Was mache ich denn falsch bei der Parameterübergabe???

              Ich habe hier nochmal all meine beteiligten Dokumente (Stylesheet, Template, SensorDaten-Dokument) beigefügt, vielleicht hilft das mir zu helfen?

              Könnte es wohl auch ein Namensraumproblem sein? Ich verwende verschiedene!


              Hier die beteiligten Dokumente:

              STYLESHEET:

              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <?xml-stylesheet type="text/xsl" href="../../CDA.xsl"?>
              <xsl:stylesheet version="2.0" 
              						xmlns="urn:hl7-org:v3"
              						xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
              						xmlns:xs="http://www.w3.org/2001/XMLSchema" 
              						xmlns:fn="http://www.w3.org/2005/xpath-functions"
              						xmlns:cda="urn:hl7-org:v3"
              						xmlns:saxon="http://icl.com/saxon"  
              					   extension-element-prefixes="saxon" >
              
              	<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
              	
              	<xsl:variable name="cdaTemplateFile" select="document('../../CDA/template_Level2_CDA_structuredBody.xml')"/>
              	<xsl:variable name="sensorFileCollection" select="collection(iri-to-uri('../../AWK/?select=*.(xml)'))"/>
              
              	<xsl:template match="/">
              		<xsl:for-each select="$sensorFileCollection">
              			<xsl:variable name="currentFile" select="current()"/>
              			<xsl:variable name="sensorFileName" select="tokenize(document-uri(.), '[\\/]')[last()]"/>
              			<xsl:variable name="resultFileName" select="concat('CDA_', position(), '_', $sensorFileName)" />
              			
              				<xsl:result-document href="{$resultFileName}">
              				
              					<xsl:if test="$cdaTemplateFile//descendant-or-self::node()[local-name()!='text'] ">
              							<xsl:apply-templates select="$cdaTemplateFile[@*] | $cdaTemplateFile/node()">
              								<xsl:with-param name="currentFile" select="$currentFile" tunnel="yes"/>
              							</xsl:apply-templates>
              					</xsl:if>
              					<xsl:if test="$cdaTemplateFile//descendant-or-self::node()[local-name()='text']">
              						<xsl:apply-templates select="$cdaTemplateFile/node()[local-name()='text']">
              							<xsl:with-param name="currentFile" select="$currentFile" tunnel="yes"/>
              						</xsl:apply-templates>
              					</xsl:if>
              
              			</xsl:result-document>
              		</xsl:for-each>
              	</xsl:template>
              	
              	<xsl:template match="@* | node()[local-name()!='text']">
              	<xsl:param name="currentFile"/>
              		<xsl:copy>
              			<xsl:apply-templates select="@* | node()" />
              		</xsl:copy>
              	</xsl:template> 
              
              	<xsl:template xmlns:cda="urn:hl7-org:v3" match="cda:text">
              	<xsl:param name="currentFile"/>
              	testtesttesttesttesttesttesttesttesttesttesttesttesttesttest
              			<xsl:copy-of select="$currentFile"/>
              		<xsl:apply-templates select="node()" />
              	</xsl:template> 
              
              </xsl:stylesheet>

              TEMPLATE (in das die Sensordaten eingefügt werden sollen):

              Code:
              <?xml version="1.0" encoding="ISO-8859-1"?>
              <?xml-stylesheet type="text/xsl" href="../../CDA/CDA.xsl"?>
              
              <ClinicalDocument
              xmlns="urn:hl7-org:v3" 
              xmlns:voc="urn:hl7-org:v3/voc"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="urn:hl7-org:v3 ..\..\CDA\schemas\CDA.xsd"
              classCode="DOCCLIN"
              moodCode="EVN">
              
              ...
              
              <component>
                <structuredBody>
                  <component>
                    <section>
              	<component>
              	  <section>
                          <text>
              <!-- 
              ****************************************
              	Hier die Sensordaten eingefüen !!!
              **************************************
              -->
                     </text>
                    </section>
                   </component>
                  </section>    
                 </component>
                </structuredBody>
               </component>
              </ClinicalDocument>

              SENSORDATEN:

              Code:
              <table xmlns="urn:hl7-org:v3">
              <tbody>
              	<tr>
              		<th>Time</th>
              		<th>numpeaks_accelerometer_transverse</th>
              		<th>numpeaks_accelerometer_longitudinal</th>
              		<th>transverse_accelerometer_point_sample</th>
              		<th>longitudinal_accelerometer_point_sample</th>
              		<th>heat_flux_average_original_rate</th>
              		<th>skin_temp_average_original_rate</th>
              		<th>transverse_accelerometer_average</th>
              		<th>longitudinal_accelerometer_average</th>
              		<th>cover_temp_average</th>
              		<th>transverse_accelerometer_MAD_graphable</th>
              		<th>longitudinal_accelerometer_MAD_graphable</th>
              		<th>STEPS</th>
              		<th>gsr_average</th>
              		<th>lying_down_irs</th>
              		<th>sleep_irs</th>
              		<th>physical_activity_irs</th>
              		<th>energy_expenditure_per_minute</th>
              		<th>event</th>
              		<th>annotation</th>
              	</tr>
              	<tr>
              		<td>1132040040000</td>
              		<td>12.0</td>
              		<td>15.0</td>
              		<td>0.1091313511133194</td>
              		<td>0.7936644554138184</td>
              		<td>192.5787353515625</td>
              		<td>26.59261131286621</td>
              		<td>0.07206787168979645</td>
              		<td>0.9533096551895142</td>
              		<td>26.385995864868164</td>
              		<td>0.5971338152885437</td>
              		<td>3.119922399520874</td>
              		<td>39.0</td>
              		<td>0.04762358218431473</td>
              		<td>0.0</td>
              		<td>0.0</td>
              		<td>0.0</td>
              		<td>6.657251358032227</td>
              		<td></td>
              		<td></td>
              	</tr>
              	<tr>
              		<td>1132040043000</td>
              		<td>15.0</td>
              		<td>18.0</td>
              		<td>0.006177246104925871</td>
              		<td>1.2725999355316162</td>
              		<td></td>
              		<td></td>
              		<td>0.058683838695287704</td>
              		<td>0.9761160612106323</td>
              		<td></td>
              		<td>0.5806611180305481</td>
              		<td>2.5543224811553955</td>
              		<td></td>
              		<td></td>
              		<td></td>
              		<td></td>
              		<td></td>
              		<td></td>
              		<td></td>
              		<td></td>
              	</tr>
              ...
              ...
              ...
              ...
                 </tbody>
              </table>

              Vielleicht nutzt das ja!?
              Das <text>-Element auszuschließen, wie Du oben vorgeschlagen hast Thomas, hat in der if-Abfrage nur bewirkt, dass das Element nicht mehr kopiert wurde.
              Die Unterscheidung im Identitäts-Template, ob es sich um Daten aus dem Template, oder denen aus der Sensor-XML handelt, scheint ein Problem zu sein. Also doch die Namensräume?

              Ich weiß echt nicht mehr weiter....hab gestern den ganzen Tag verschiedenes ausprobiert!

              Comment


              • #8
                Vermutlich liegt ein Namensraumproblem vor, da die betroffenen Elemente im Default-NS xmlns="urn:hl7-org:v3" liegen.

                Zum formalen Testen habe ich diese test.xml verwendet:
                Code:
                <?xml version="1.0" encoding="ISO-8859-1"?>
                <ClinicalDocument xmlns="urn:hl7-org:v3" xmlns:voc="urn:hl7-org:v3/voc"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="urn:hl7-org:v3 ..\..\CDA\schemas\CDA.xsd"
                  classCode="DOCCLIN" moodCode="EVN">
                  <component>
                    <structuredBody>
                      <component>
                        <section>
                          <component>
                            <section>
                              <text></text>
                            </section>
                          </component>
                        </section>
                      </component>
                    </structuredBody>
                  </component>
                </ClinicalDocument>
                In sensor.xml liegt die komplette Tabelle vor:
                Code:
                <?xml version="1.0" encoding="ISO-8859-1"?>
                <table xmlns="urn:hl7-org:v3">...</table>
                Mit diesem Stylesheet test.xsl funktioniert die Transformation. Beachte das willkürlich gewählte Präfix h17:
                Code:
                <?xml version="1.0" encoding="ISO-8859-1"?>
                <xsl:stylesheet version="2.0" xmlns="urn:hl7-org:v3"
                  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                  xmlns:xs="http://www.w3.org/2001/XMLSchema"
                  xmlns:fn="http://www.w3.org/2005/xpath-functions"
                  xmlns:cda="urn:hl7-org:v3" xmlns:saxon="http://icl.com/saxon"
                  extension-element-prefixes="saxon" xmlns:h17="urn:hl7-org:v3"
                  exclude-result-prefixes="cda fn xs h17">
                
                  <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
                  <xsl:variable name="sensorfile" select="'sensor.xml'"/>
                
                  <xsl:template match="@* | node()">
                    <xsl:copy>
                      <xsl:apply-templates select="@* | node()"/>
                    </xsl:copy>
                  </xsl:template>
                
                  <xsl:template match="h17:text">
                    <text>
                      <xsl:copy-of select="fn:doc($sensorfile)/h17:table"/>
                    </text>
                  </xsl:template>
                </xsl:stylesheet>
                Ergebnis:
                Code:
                <?xml version="1.0" encoding="ISO-8859-1"?>
                <ClinicalDocument xmlns="urn:hl7-org:v3" xmlns:voc="urn:hl7-org:v3/voc"
                                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                  xsi:schemaLocation="urn:hl7-org:v3 ..\..\CDA\schemas\CDA.xsd"
                                  classCode="DOCCLIN"
                                  moodCode="EVN">
                  <component>
                      <structuredBody>
                         <component>
                            <section>
                               <component>
                                  <section>
                                     <text>
                                        <table>
                                           <tbody>
                	             <!-- ... der Rest ... -->
                                           </tbody>
                                        </table>
                                     </text>
                                  </section>
                               </component>
                            </section>
                         </component>
                      </structuredBody>
                  </component>
                </ClinicalDocument>

                Comment


                • #9
                  Danke für Deine Mühen Thomas!

                  Für ein einzelnes Dokument hatte ich die Transformation ja zuvor auch schon hinbekommen. Der Namensraum, den ich verwendet hatte, heißt "xmlns:cda="urn:hl7-org:v3", also das Gleicht in grün
                  Dass die Sensordaten nicht an der korrekten Position geschrieben wurden hatte ander Ursachen.

                  Die schwierigkeit liegt halt in der verarbeitung aller Dokumente im Verzeichnis!


                  Ich habe das Stylesheet noch einmal umgeschrieben:

                  Code:
                  <?xml version="1.0" encoding="UTF-8"?>
                  <?xml-stylesheet type="text/xsl" href="../../CDA.xsl"?>
                  <xsl:stylesheet version="2.0" 
                  						xmlns="urn:hl7-org:v3" 
                  						xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                  						xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                  						xmlns:fn="http://www.w3.org/2005/xpath-functions" 
                  						xmlns:cda="urn:hl7-org:v3" 
                  						xmlns:saxon="http://saxon.sf.net/"
                  						extension-element-prefixes="saxon">
                  						
                  	<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
                  
                  	<xsl:variable name="sensorFileCollection" select="collection(iri-to-uri('../../AWK/?select=*.(xml)'))"/>
                  	<xsl:variable name="cdaTemplateFile" select="document('../../CDA/template_Level2_CDA_structuredBody.xml')"/>
                  	<xsl:variable name="fileCount" select="count($sensorFileCollection)"/>
                  	
                  		<xsl:variable name="currentFile">
                  			<xsl:for-each select="for $x in $sensorFileCollection return saxon:discard-document($x)">
                  				<xsl:apply-templates/>
                  			</xsl:for-each>
                  		</xsl:variable>
                  
                  	<xsl:template match="/">
                  
                  		<xsl:for-each select="$sensorFileCollection">
                  			<xsl:variable name="sensorFileName" select="tokenize(document-uri(.), '[\\/]')[last()]"/>
                  			<xsl:variable name="resultFileName" select="concat('CDA_', position(), '_', $sensorFileName)"/>
                  
                  			<xsl:result-document href="{$resultFileName}">
                  				<xsl:apply-templates select="$cdaTemplateFile/node()"/>
                  			</xsl:result-document>
                  
                  		</xsl:for-each>
                  	</xsl:template>
                  	
                  		<xsl:template match="@* | node()[local-name()!='text']">
                  		<xsl:copy>
                  			<xsl:apply-templates select="@* | node()"/>
                  		</xsl:copy>
                  	</xsl:template>
                  	
                  	<xsl:template xmlns:cda="urn:hl7-org:v3" match="cda:text">
                  		<xsl:copy>
                  			kaaaaaaaaacke maaaaaaaaaaaaaaaaaaaaaaaaaan!!!!!!!!!
                  			<xsl:copy-of select="$currentFile" saxon:read-once="yes"/>
                  		</xsl:copy>
                  		<xsl:apply-templates select="node()"/>
                  	</xsl:template>
                  	
                  </xsl:stylesheet>

                  Das Problem ist meie Variable "currentFile":

                  Code:
                  <xsl:variable name="currentFile">
                  	<xsl:for-each select="for $x in $sensorFileCollection return saxon:discard-document($x)">
                  		<xsl:apply-templates/>
                  	</xsl:for-each>
                  </xsl:variable>

                  Mit dem obigen Stylesheet werden alle Sensor-XML-Dokumente in einem Verzeichnis abarbeitet und jeweils ein korrekt benanntes Ergebnisdokument beschrieben, ABER es werden die Inhalte ALLER Sensordaten-Dokumente innerhalb des <text>-Elements kopiert und nicht, wie ja gewünscht, nur die aktuelle Datei!

                  Das sieht dann so aus, was schonmal nicht sooo schlecht ist:

                  Code:
                  <?xml version="1.0" encoding="ISO-8859-1"?>
                  <?xml-stylesheet type="text/xsl" href="../../CDA/CDA.xsl"?>
                  <ClinicalDocument xmlns="urn:hl7-org:v3" xmlns:voc="urn:hl7-org:v3/voc"
                                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                    xsi:schemaLocation="urn:hl7-org:v3 ..\..\CDA\schemas\CDA.xsd"
                                    classCode="DOCCLIN"
                                    moodCode="EVN">
                    <component>
                      <structuredBody>
                        <component>
                           <section>
                              <text>
                  		<table>
                                                 <!-- Sensordaten File 1 -->
                                   </table>
                                   <table>
                                                 <!-- Sensordaten File 2 -->
                                   </table>
                                   ...
                                   ...
                                </text>							
                              </section>
                            </component>
                          </section>    
                        </component>
                      </structuredBody>
                    </component>
                  </ClinicalDocument>
                  Wie kann ich es schaffen, dass mir "currentFile" wirklich nur die Sensordaten aus der aktuellen Datei zum Zeitpunkt des Kopierens übergibt und nicht die Inhalte aller Sensor-Dateien???

                  Kann ich irgendwie auf das $x in der for-schleife zugreifen, oder als Parameter in <xsl:apply-templates name="file" select="$x"> übergeben???

                  Comment


                  • #10
                    Nur noch als Vermutung, weil ich das nicht überblicke: Wenn der Name der aktuellen Datei einen Rückschluss auf die Sensor-Datei zulässt, dann frage eben explizit diese Datei ab und verwende kein xsl:for-each.

                    Comment


                    • #11
                      Mhh...was ich möchte weißt Du aber schon?

                      Als Ergebnis hätte ich halt gern pro Sensordatei in meinem Verzeichnis, was durch die "collection" repräsentiert wird, jeweils ein result-document, welches das Template+Sensordaten(file-x) beinhaltet.

                      So dass ich am Ende genauso viele Ergebnisdokumente bekomme, wie Sensordateien eingelesen wurden, die dann so aussehen:

                      Code:
                      <?xml version="1.0" encoding="ISO-8859-1"?>
                      <?xml-stylesheet type="text/xsl" href="../../CDA/CDA.xsl"?>
                      <ClinicalDocument xmlns="urn:hl7-org:v3" xmlns:voc="urn:hl7-org:v3/voc"
                                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                        xsi:schemaLocation="urn:hl7-org:v3 ..\..\CDA\schemas\CDA.xsd"
                                        classCode="DOCCLIN"
                                        moodCode="EVN">
                        <component>
                          <structuredBody>
                            <component>
                               <section>
                                  <text>
                      		<table>
                                                     <!-- Sensordaten File 1 -->
                                       </table>
                                    </text>							
                                  </section>
                                </component>
                              </section>    
                            </component>
                          </structuredBody>
                        </component>
                      </ClinicalDocument>
                      
                      ------------------------------------------------
                      
                      <?xml version="1.0" encoding="ISO-8859-1"?>
                      <?xml-stylesheet type="text/xsl" href="../../CDA/CDA.xsl"?>
                      <ClinicalDocument xmlns="urn:hl7-org:v3" xmlns:voc="urn:hl7-org:v3/voc"
                                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                        xsi:schemaLocation="urn:hl7-org:v3 ..\..\CDA\schemas\CDA.xsd"
                                        classCode="DOCCLIN"
                                        moodCode="EVN">
                        <component>
                          <structuredBody>
                            <component>
                               <section>
                                  <text>
                                       <table>
                                                     <!-- Sensordaten File 2 -->
                                       </table>
                                    </text>							
                                  </section>
                                </component>
                              </section>    
                            </component>
                          </structuredBody>
                        </component>
                      </ClinicalDocument>
                      
                      ...
                      ...
                      ...
                      usw. für alle Dateien im Verzeichnis halt...
                      Das muss doch irgendwie gehen Sonst bin ich aufgeschmissen


                      Das Problem was ich habe ist halt, dass ich nicht weiß, wie ich die aktuelle Datei ansprechen kann, bzw. wie ich durch die collection iterieren kann. Scheinbar schmeißt er mir ja doch immer den Inhalt der kompletten collection auf einmal heraus.

                      Welches for-each meinst du Thomas? Das in der Variable?

                      Comment


                      • #12
                        Alternativvorschlag: Nimm ein Dummy-XML-Dokument <root/> und transformiere mit einem Stylesheet, welches die Collection durchgeht und jeweils das Hauptdokument und die variierenden Sensordateien über die fn:doc()-Funktion verarbeitet. Das dürfte wesentlich kompakter und verständlicher formulierbar sein.

                        Comment


                        • #13
                          Mhh....das verstehe ich nicht ganz. Wie meinst Du das?

                          Die Dateinamen in das <root>-XML schreiben und dann von dort aus auslesen?

                          Kannst Du das beispielhaft darstellen?

                          Comment


                          • #14
                            Ich dachte an dieses Vorgehen: Das in allen Ausgabedokumenten identische Grundgerüst (hier HTML) wird im Stylesheet angegeben und darin jeweils eine externe Datei engebunden.

                            root.xml:
                            Code:
                            <?xml version="1.0" encoding="ISO-8859-1"?>
                            <root/>
                            main.xsl:
                            Code:
                            <?xml version="1.0" encoding="ISO-8859-1"?>
                            <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn">
                            
                              <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
                            
                              <xsl:variable name="files" select="('table1.xml','table2.xml','table3.xml')"/>
                            
                              <xsl:template match="/">
                                <xsl:for-each select="$files">
                                  <xsl:result-document href="file:///C:/Temp/output/out{position()}.xml">
                                    <html>
                                      <head>
                                        <title>Test</title>
                                      </head>
                                      <body>
                                        <xsl:copy-of select="fn:doc(.)"/>
                                      </body>
                                    </html>
                                  </xsl:result-document>
                                </xsl:for-each>
                              </xsl:template>
                            
                            </xsl:stylesheet>
                            Im Beispiel gibt es drei XML-Dokumente table1.xml, table2.xml und table3.xml:
                            Code:
                            <?xml version="1.0" encoding="ISO-8859-1"?>
                            <table>
                              <tbody>
                                <tr>
                                  <td>1</td><!-- hier 2 bzw. 3 in den Dokumenten table2.xml/table3.xml -->
                                </tr>
                              </tbody>
                            </table>
                            Transformiert wird root.xml mit main.xml. Als Ergebnis entstehen hier drei Ausgabedokumente (out?.xml), z. B. out1.xml für table1.xml:
                            Code:
                            <?xml version="1.0" encoding="ISO-8859-1"?>
                            <html>
                               <head>
                                  <title>Test</title>
                               </head>
                               <body>
                                  <table>
                                     <tbody>
                                        <tr>
                                           <td>1</td>
                                        </tr>
                                     </tbody>
                                  </table>
                               </body>
                            </html>

                            Comment


                            • #15
                              Das würde wohl gehen, allerdings meckert er bei mir über das fn:doc(.)!

                              Wenn ich meine collection() benutze und dann ein <xsl:copy-of select="/"/> im <text>-Element aufrufe funktioniert es.

                              Allerdings ist das nicht wirklich gewünscht, da ich mein Template in das Stylesheet schreiben muss und es somit nicht mehr eigenständig und die Dateien modular austauschbar sind!

                              Gibt es wirklich keine Lösung für das Schleifen-Problem???

                              Ein anderes Problem tritt nun auch noch auf wie ich merke. Die Sensor-XML Files sind teilweise dermaßen groß (~10MB) dass der Prozessor eine Java Heap Size Exception wirft, also der Speicher voll ist!
                              Ich habe auf http://www.saxonica.com gelesen, dass es eine Streaming-Funktion für sehr große Dokumente gibt - allerdings nur für die kommerzielle Saxon-SA Version!

                              Comment

                              Working...
                              X