2011-01-11 15 views
1

Ich habe ein Szenario, in dem ich ein. NET-Dataset in eine XML-Datei exportieren, aber ich möchte die Struktur der XML-Ausgabe in eine hierarchische Struktur zu transformieren. Im Folgenden sehen Sie das Format des Datasets, das von der Methode "dataset.xmlwrite()" exportiert wurde.XML-Transformation von Dataset.Writexml XML

<NewDataSet> 
    <Table> 
     <id>100</id> 
     <empname>Joe Smith</empname> 
     <phone>111-111-1111</phone> 
     <mobile>222-222-2222</mobile> 

    </Table> 
    <Table> 
     <id>101</id> 
     <empname>Ann Jensen</empname> 
     <phone>111-111-0000</phone> 
     <mobile>222-222-0000</mobile> 
    </Table> 
<NewDataSet> 

Ich möchte es in die folgende Struktur konvertieren. Ich bin ein Neuling bei Xsl Transformationen und ich bin mir nicht sicher, wie das <Table> Element für jeden Datensatz im Dataset zu wiederholen.

<NewDataSet> 
    <Table> 
     <employee id="100"> 
      <empname>Joe Smith</empname> 
      <phone>111-111-1111</phone> 
      <mobile>222-222-2222</mobile> 
     </employee> 
     <employee id="101"> 
      <empname>Ann Jensen</empname> 
      <phone>111-111-0000</phone> 
      <mobile>222-222-0000</mobile> 
     </employee> 
    </Table> 
<NewDataSet> 

Ich habe versucht, eine Kombination von xsl: for-each und xsl: if-Anweisungen, was zu bekommen ich wollte, aber bisher habe ich nicht in der Lage gewesen, um es zu arbeiten. Jede Hilfe würde sehr geschätzt werden.

+0

Gute Frage, +1 den Trick. Sehen Sie meine Antwort für eine einfache und leistungsstarke Lösung, die vollständig im Sinne von XSLT ist: verwendet und überschreibt die Identitätsregel. Beachten Sie auch, dass keine bedingten XSLT-Anweisungen verwendet werden. :) –

Antwort

2

Diese Transformation:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Table[1]"> 
    <Table> 
    <xsl:apply-templates select="../Table/id"/> 
    </Table> 
</xsl:template> 

<xsl:template match="Table[position()>1]"/> 

<xsl:template match="Table/id"> 
    <employee id="{.}"> 
    <xsl:apply-templates select= 
     "following-sibling::node()"/> 
    </employee> 
</xsl:template> 
</xsl:stylesheet> 

wenn sie auf dem vorgesehenen XML Dokument angewendet (korrigiert werden wohlgeformt):

<NewDataSet> 
    <Table> 
     <id>100</id> 
     <empname>Joe Smith</empname> 
     <phone>111-111-1111</phone> 
     <mobile>222-222-2222</mobile> 
    </Table> 
    <Table> 
     <id>101</id> 
     <empname>Ann Jensen</empname> 
     <phone>111-111-0000</phone> 
     <mobile>222-222-0000</mobile> 
    </Table> 
</NewDataSet> 

erzeugt die gewünschte, korrekte Ergebnis:

<NewDataSet> 
    <Table> 
     <employee id="100"> 
     <empname>Joe Smith</empname> 
     <phone>111-111-1111</phone> 
     <mobile>222-222-2222</mobile> 
     </employee> 
     <employee id="101"> 
     <empname>Ann Jensen</empname> 
     <phone>111-111-0000</phone> 
     <mobile>222-222-0000</mobile> 
     </employee> 
    </Table> 
</NewDataSet> 

Erklärung:

  1. Die Identität der Regel Kopien jeder Knoten "wie sie ist".

  2. Das erste Table Element wird durch eine übergeordnete Vorlage abgestimmt. Dies erstellt die einzige Table im Ergebnis und wendet Vorlagen auf die Kinder aller Table Elemente.

  3. id Das Element wird durch ein zwingendes Vorlage angepaßt, dass es in ein Element employee wandelt ein id Attribut mit dem Wert des id Element. Dies gilt auch für Vorlagen innerhalb des Elements employee für alle anderen Geschwister von id. Sie werden unverändert von der Identitätsvorlage kopiert.

+0

fancy xslt code – dvhh

+0

@dvhh: Ja, XSLT ist eine extrem elegante und mächtige Sprache - vor allem aufgrund der "Identity Rule" Design-Muster. –

+0

+1. Bessere Antwort. – Flack

2

sollte diese

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="/"> 
    <Table> 
    <xsl:for-each select="/NewDataSet/Table"> 
     <employee> 
      <xsl:attribute name="id"><xsl:value-of select="id/."/></xsl:attribute> 
      <xsl:for-each select="*"> 
       <xsl:choose> 
        <xsl:when test="name() = 'id' "/> 
        <xsl:otherwise> 
         <xsl:copy-of select="."/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:for-each> 
     </employee> 
    </xsl:for-each> 
    </Table> 
</xsl:template> 
</xsl:stylesheet> 
+1

Es funktioniert! Danke für die Antwort. – Clinemi

+0

Erwähnen Sie es nicht, meine Antwort ist ein bisschen einfach im Vergleich zu @ Dimitres one – dvhh

+0

Danke, ich bevorzuge die Looping-Lösungen über die Vorlage basiert, wie ich meinen Kopf um sie leichter bekommen und damit beugen sie zu meinem Willen! –