Frage

Es muss eine generische Art und Weise sein, einiges hierarchisches XML zu transformieren, wie:

<element1 A="AValue" B="BValue">
   <element2 C="DValue" D="CValue">
      <element3 E="EValue1" F="FValue1"/>
      <element3 E="EValue2" F="FValue2"/>
   </element2>
   ...
</element1>

in die abgeflachte XML (HTML) Kommissionierung ausgewählte Attribute auf dem Weg nach oben und verschiedenen Markierungen für die Attribute, vorausgesetzt Spaltenüberschriften werden.

<table>
   <tr>
     <th>A_Label</th>
     <th>D_Label</th>
     <th>E_Label</th>
     <th>F_Label</th>
   </tr>
   <tr>
     <td>AValue</td>
     <td>DValue</td>
     <td>EValue1</td>
     <td>FValue1</td>
   </tr>
   <tr>
     <td>AValue</td>
     <td>DValue</td>
     <td>EValue2</td>
     <td>FValue2</td>
   </tr>
<table>

OK, also gibt es keine generische Lösung aufgrund der Attribut Neuetikettierung aber Sie bekommen, was ich hoffentlich bedeuten. Ich habe gerade auf dem ganzen XSLT / XPATH Sachen gestartet, damit ich es arbeiten werde rechtzeitig, aber Anhaltspunkte wäre nützlich.

War es hilfreich?

Lösung

Ich bin nicht 100% sicher, was Sie versuchen, diese Lösung zu tun, sondern kann funktionieren, wenn Ihr element1, element2 und element3 konsequent verschachtelt sind.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <table>
            <xsl:apply-templates select="//element3"></xsl:apply-templates>
        </table>
    </xsl:template>

    <xsl:template match="element3">
        <tr>
            <td><xsl:value-of select="../../@A"/></td>
            <td><xsl:value-of select="../../@B"/></td>
            <td><xsl:value-of select="../@C"/></td>
            <td><xsl:value-of select="../@D"/></td>
            <td><xsl:value-of select="@E"/></td>
            <td><xsl:value-of select="@F"/></td>
        </tr>
        <xsl:apply-templates select="*"></xsl:apply-templates>
    </xsl:template>

</xsl:stylesheet>

Andere Tipps

Ich brauchte eine ähnliche XSLT aber mit unbekannter Tiefe, hier ist, wie ich es tat.

Als erstes einen Wrapper für die resultierende HTML-Tabelle / def Liste hinzufügen und die Template-Modus aufrufen = „kotzen“ unser XML-Struktur zu glätten:

<xsl:element name="div">
    <xsl:attribute name="class" select="puke" />
    <xsl:apply-templates select="$notice" mode="puke" />
</xsl:element>  

Hier haben wir jeden Knoten entsprechen seinen Inhalt (zum Beispiel Text ()) und seine Attribute anzuzeigen. Wir tun dies rekursiv. Früher habe ich dl / dt / dd, weil mein Quellbaum einen komplexen Baum war, der nicht als ein Abflachen werden kann.

<!-- @description: 
    Display all field from the notice so the customer can tell what he want
-->
<xsl:template match="node()" mode="puke">
<xsl:message>
    puking : <xsl:value-of select="local-name( . )" />
</xsl:message>
    <xsl:element name="dl">
        <xsl:element name="dt">
            <xsl:attribute name="class">tagName</xsl:attribute> 
            <xsl:value-of select="local-name( . )" />
        </xsl:element>
        <xsl:element name="dd">
            <xsl:attribute name="class">tagText</xsl:attribute>
            <xsl:value-of select="text()" /></xsl:element> 
        <xsl:element name="dl">
            <xsl:attribute name="class">attr</xsl:attribute>
            <!-- display attribute -->
            <xsl:apply-templates select="@*" />
        </xsl:element>
    </xsl:element>
    <!-- recursive call on node() -->
    <xsl:apply-templates select="./*" mode="puke" />    
</xsl:template>

Match-Attribut eines bestimmten Knotens und sie anzuzeigen.                                         
                                    

Die CSS in die resultierende HTML formatiert werden:

<style>
.puke {
    background-color: #BDD6DE;
    clear: both;
}
.tagName, .attrName {
    float: left;
}
.tagText, .attrText {
    clear: right;
}
</style>

Wir haben bereits ein Pro * C Programm aus einer Oracle-Datenbank zu lesen, ruft es ein Perl-Skript, das wiederum einige Java führt Daten im XML-Format von der oben genannten Datenbank zu extrahieren für eine Batch-Datei aufrufen einige Vbscript auszuführen FTPing die Datei auf einen anderen Server. Ich hatte wirklich gehofft, für etwas in Fortran.

Die ursprüngliche Frage muss geklärt werden:

  • Was passiert mit bValue und cValue in der ursprünglichen Frage? Gibt es einen Grund, warum sie nicht Teil der abgeflachte Struktur sein sollten?
  • Sie alle Elemente in der XML-doc haben zwei Attribute oder ist dies völlig willkürlich?
  • Gibt es nur drei Arten von Elementen und werden sie verschachtelt immer, wie im Beispiel gezeigt?
  • Kann Ihr element1 selbst wiederholt werden oder ist dies das Wurzelelement Ihres Dokuments?

In XSLT ist es möglich, sehr allgemein Transformatoren zu schreiben, aber es ist oft viel einfacher, einen Stylesheet zu schreiben, ein Dokument zu transformieren, wenn Sie alle bekannten Einschränkungen berücksichtigen können.

Ich habe eine erweiterte Version der Vorlage verwendet unten strukturierte XML zu glätten. Achtung: Es gab einige fallspezifischen Code in der ursprünglichen Version (es stellte sich tatsächlich die XML-Daten in CSV), dass ich diese Version nur ausgezogen und habe ich nicht getestet.

Die grundlegende Art und Weise sollte es funktioniert klar sein: es alles druckt, die nicht Knoten Kinder haben und ansonsten ruft rekursiv die Vorlage auf dem Knoten (), die Kinder haben. Ich glaube nicht, es behandelt Attribute und Kommentare richtig, wie es jetzt ist, aber das sollte nicht schwer zu beheben.

<?xml version="1.0" encoding="UTF-8"?>

<!-- XSL template to flatten structured XML, before converting to CSV. -->
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <xsl:strip-space elements="*" /> 

    <xsl:template match="/">
        <xsl:apply-templates select="//yourElementsToFlatten"/>
    </xsl:template>

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

    <xsl:template match="@*|node()">
        <xsl:choose>
            <!-- If the element has multiple childs, call this template 
                on its children to flatten it-->
            <xsl:when test="count(child::*) > 0">
                <xsl:apply-templates select="@*|node()"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:value-of select="text()" />
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top