2017-10-11 2 views
0

ich mit aufeinander folgenden Tags anstelle von verschachtelten Tags eine XML-Datei haben, wie folgt aus:Wie XQuery verwenden aufeinanderfolgende Tags in verschachtelte Tags oder Tisch zu verwandeln

<title> 
    <subtitle> 
     <topic att="TopicTitle">Topic title 1</topic> 
     <content att="TopicSubtitle">topic subtitle 1</content> 
     <content att="Paragraph">paragraph text 1</content> 
     <content att="Paragraph">paragraph text 2</content> 
     <content att="TopicSubtitle">topic subtitle 2</content> 
     <content att="Paragraph">paragraph text 1</content> 
     <content att="Paragraph">paragraph text 2</content> 

     <topic att="TopicTitle">Topic title 2</topic> 
     <content att="TopicSubtitle">topic subtitle 1</content> 
     <content att="Paragraph">paragraph text 1</content> 
     <content att="Paragraph">paragraph text 2</content> 
     <content att="TopicSubtitle">topic subtitle 2</content> 
     <content att="Paragraph">paragraph text 1</content> 
     <content att="Paragraph">paragraph text 2</content> 
    </subtitle> 
</title> 

I XQuery in BaseX bin mit und ich möchte zu konvertieren sie es mit den folgenden Spalten zu einer Tabelle:

Title  Subtitle  TopicTitle  TopicSubtitle  Paragraph 
Irrelevant Irrelevant Topic title 1 Topic Subtitle 1 paragraph text 1 
Irrelevant Irrelevant Topic title 1 Topic Subtitle 1 paragraph text 2 
Irrelevant Irrelevant Topic title 1 Topic Subtitle 2 paragraph text 1 
Irrelevant Irrelevant Topic title 1 Topic Subtitle 2 paragraph text 2 
Irrelevant Irrelevant Topic title 2 Topic Subtitle 1 paragraph text 1 
Irrelevant Irrelevant Topic title 2 Topic Subtitle 1 paragraph text 2 
Irrelevant Irrelevant Topic title 2 Topic Subtitle 2 paragraph text 1 
Irrelevant Irrelevant Topic title 2 Topic Subtitle 2 paragraph text 2 

ich bin neu in XQuery und XPath, aber ich verstehe schon die Grundlagen auf, wie durch die Knoten navigieren und die auswählen, die ich brauche. Was ich noch nicht weiß ist, wie man mit fortlaufenden Daten arbeitet, die ich in eine verschachtelte XML oder Tabelle (CSV?) Konvertieren möchte. Kann jemand helfen?

Antwort

5

Sie können die flache XML in eine verschachtelte Version umwandeln, indem Sie tumbling window (https://www.w3.org/TR/xquery-30/#id-windows) verwenden, z.

for tumbling window $w in title/subtitle/* 
    start $t when $t instance of element(topic) 
return 
    <topic 
     title="{$t/@att}"> 
     { 
      for tumbling window $content in tail($w) 
       start $c when $c/@att = 'TopicSubtitle' 
      return 
       <subtopic 
        title="{$c/@att}"> 
        { 
         tail($content) ! <para>{node()}</para> 
        } 
       </subtopic> 
     } 
    </topic> 

gibt

<topic title="TopicTitle"> 
    <subtopic title="TopicSubtitle"> 
     <para>paragraph text 1</para> 
     <para>paragraph text 2</para> 
    </subtopic> 
    <subtopic title="TopicSubtitle"> 
     <para>paragraph text 1</para> 
     <para>paragraph text 2</para> 
    </subtopic> 
</topic><topic title="TopicTitle"> 
    <subtopic title="TopicSubtitle"> 
     <para>paragraph text 1</para> 
     <para>paragraph text 2</para> 
    </subtopic> 
    <subtopic title="TopicSubtitle"> 
     <para>paragraph text 1</para> 
     <para>paragraph text 2</para> 
    </subtopic> 
</topic> 

auf dieser Grundlage Ich denke, man kann dann die gesamte Transformation getrennt Daten Semikolon mit

string-join(
<title> 
    <subtitle> 
     { 
      for tumbling window $w in title/subtitle/* 
       start $t when $t instance of element(topic) 
      return 
       <topic 
        title="{$t/@att}" 
        value="{$t}"> 
        { 
         for tumbling window $content in tail($w) 
          start $c when $c/@att = 'TopicSubtitle' 
         return 
          <subtopic 
           title="{$c/@att}" 
           value="{$c}"> 
           { 
            tail($content) ! <para>{node()}</para> 
           } 
          </subtopic> 
        } 
       </topic> 
     } 
    </subtitle> 
</title>//para ! string-join(ancestor-or-self::* ! (text(), @value, 'Irrelevant')[1], ';'), '&#10;') 
+0

Dieser groß ist. Genau das, was ich brauchte. Nachdem ich mehr über das taumelnde Fenster geforscht habe, bezweifle ich, dass ich es selbst gefunden hätte. Es dauerte ein wenig, um es an die Datei anzupassen, die ich habe, aber es funktioniert jetzt mit mehreren verschachtelten taumelnden Fenstern. Weil es ein bisschen schmutzig scheint, wollte ich fragen, weißt du von einem besseren Weg das zu tun? Ich meine, benutzt Java, Python oder eine andere Sprache besser für diese Art von Aufgabe? Danke für Ihre Hilfe! – ChuyTM

+0

Für mich, die meist XSLT (wo Sie verschachtelte 'xsl: für jede Gruppe Gruppe starten-mit 'verwenden könnte) fühlt es sich bereits schmutzig mit XQuery, aber ich denke, diese Sprachen sind eine gute Wahl für den Umgang mit XML . Wenn Sie nach etwas besser strukturiertem suchen, um XML mit XQuery in CSV zu konvertieren, dann überprüfen Sie https://github.com/CliffordAnderson/XQuery4Humanists/blob/master/05-Generating-JSON-and-CSV.md. Was Python angeht, kenne ich Python nicht gut genug und selbst wenn ich wüsste, dass es dann darauf ankommt, welches Modul du installieren kannst. –

+0

Mit reinem Java und den integrierten XML-Klassen würde es meiner Meinung nach viel Code erfordern. Ich kenne die Java 8-Streaming/Gruppierung nicht gut genug, um die Menge an Code zu schätzen, die dort benötigt würde. –

1

Obwohl Positions Gruppierung dieser Art der allgemeinste Ansatz ist von Problem (das heißt, Windows in XQuery 3.0+, for-each-group/@group-starting-with in XSLT 2.0+, wie von Martin Honnen beschrieben) taumelt. Ich denke nicht, dass es hier unbedingt notwendig ist, weil Sie nicht sind tatsächlich versuchen, die implizite hierarchische Struktur der Daten zu nutzen.

Insbesondere Sie konvertieren eine flache Struktur mit impliziter Hierarchie in eine andere flache Struktur mit impliziter Hierarchie, und man kann mit etwas entlang der folgenden Zeilen tun:

<table>{ 
    for $para in title/subtitle/content[@att='paragraph'] 
    return <row> 
     <cell>irrelevant</cell> 
     <cell>irrelevant</cell> 
     <cell>{$para/preceding-sibling::topic[1]/string()}</cell> 
     <cell>{$para/preceding-sibling::content[@att='TopicSubtitle'][1]/string()}</cell> 
     <cell>{$para/string()}</cell> 
    </row> 
}</table> 
Verwandte Themen