2012-12-30 21 views
5

Ich habe eine XML-Datei und ich muss es in XQuery konvertieren. Sehen Sie einen einfachen Satz von XML:XML zu CSV Umwandlung mit XQuery

books[book] 
book[@isbn, title, descrption] 

zB:

<books> 
    <book isbn="1590593049"> 
     <title>Extending Flash MX 2004</title> 
     <description> 
     Using javascript alongwith actionscript 3.0 and mxml.</description> 
    </book> 
    <book isbn="0132149184"> 
     <title>Java Software Solutions</title> 
     <description> 
      Complete book full of case studies on business solutions and design concepts while building mission critical 
      business applications. 
     </description> 
    </book> 

Wie es in CSV-Format mit XQuery konvertieren? Die CSV wird von Microsoft Excel,

verwendet, so dass es durch Kommata getrennt (,) Zeichen und Sonderzeichen sollte escaped werden.

Antwort

4

Ein reiner XPath 2.0 Ausdruck:

for $b in /*/book 
    return 
     concat(escape-html-uri(string-join(($b/@isbn, 
              $b/title, 
              $b/description 
             ) 
              /normalize-space(), 
             ",") 
          ), 
      codepoints-to-string(10)) 

XSLT 2 - basierte Überprüfung:

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

<xsl:template match="/"> 
    <xsl:sequence select= 
    "for $b in /*/book 
     return 
     concat(escape-html-uri(string-join(($b/@isbn, 
              $b/title, 
              $b/description 
              ) 
               /normalize-space(), 
              ',') 
           ), 
       codepoints-to-string(10))"/> 
</xsl:template> 
</xsl:stylesheet> 

Wenn diese Transformation auf dem bereitgestellten XML Dokument angewandt wird (korrigierter von seinem Fehlbildung):

<books> 
    <book isbn="1590593049"> 
     <title>Extending Flash MX 2004</title> 
     <description> 
     Using javascript alongwith actionscript 3.0 and mxml.</description> 
    </book> 
    <book isbn="0132149184"> 
     <title>Java Software Solutions</title> 
     <description> 
      Complete book full of case studies on business solutions and design concepts while building mission critical 
      business applications. 
     </description> 
    </book> 
</books> 

das gewünschte, korrekte Ergebnis wird produziert:

1590593049,Extending Flash MX 2004,Using javascript alongwith actionscript 3.0 and mxml. 
0132149184,Java Software Solutions,Complete book full of case studies on business solutions and design concepts while building mission critical business applications. 

aktualisieren:

In einem Kommentar der OP fordert alle im Text durch ein Zitat und umgeben sein Komma (Danach wird jedes Zitat durch zwei Anführungszeichen ersetzt, und schließlich, wenn das Ergebnis von wholw ein Zitat enthält, muss es von (einzelnen) Anführungszeichen umgeben sein.

ist hier ein reiner Ausdruck XPath 2.0, die diese erzeugt: dagegen wird

for $b in /*/book, 
    $q in codepoints-to-string(34), 
    $NL in codepoints-to-string(10), 
    $isbn in normalize-space(replace($b/@isbn, ',', concat($q,',',$q))), 
    $t in normalize-space(replace($b/title, ',', concat($q,',',$q))), 
    $d in normalize-space(replace($b/description, ',', concat($q,',',$q))), 
    $res in 
    escape-html-uri(string-join(($isbn,$t,$d), ',')), 
    $res2 in replace($res, $q, concat($q,$q)) 
    return 
    if(contains($res2, $q)) 
     then concat($q, $res2, $q, $NL) 
     else concat($res2, $NL) 

Wenn dieser XPath-Ausdruck XML-Dokument (mit einem neuen Testfall erweitert) ausgewertet:

<books> 
    <book isbn="1590593049"> 
     <title>Extending Flash MX 2004</title> 
     <description> 
     Using javascript alongwith actionscript 3.0 and mxml.</description> 
    </book> 
    <book isbn="0132149184"> 
     <title>Java Software Solutions</title> 
     <description> 
      Complete book full of case studies on business solutions and design concepts while building mission critical 
      business applications. 
     </description> 
    </book> 
    <book isbn="XX1234567"> 
     <title>Quotes and comma</title> 
     <description> 
      Hello, World from "Ms-Excel" 
     </description> 
    </book> 
</books> 

das gewünschte, korrekte Ergebnis wird produziert:

1590593049,Extending Flash MX 2004,Using javascript alongwith actionscript 3.0 and mxml. 
0132149184,Java Software Solutions,Complete book full of case studies on business solutions and design concepts while building mission critical business applications. 
"XX1234567,Quotes and comma,Hello"","" World from ""Ms-Excel""" 
+0

aber wenn es reine XPath 2 wäre würde es nicht interpretieren die ' ' als Zeilenumbruch – BeniBela

+0

@BeniBela, Ihre Frage ist nicht klar - Ich aktualisierte meine Antwort mit einem XSLT-Transformation, die den gleichen XPath-Ausdruck verwendet Wenn dies kein gültiger XPath-Ausdruck wäre, gäbe es einen Fehler, aber die Umwandlung funktioniert ohne Probleme –

+0

Nun, wenn Sie es in XSLT aufnehmen, ist es nicht mehr * reiner * XPath. Dann ersetzt der XML-Parser das & # xA. Wenn Sie nur den * pure * XPath ohne XSLT ausführen, erhalten Sie: '1590593049, Flash MX 2004 erweitern, Javascript mit ActionScript 3.0 und MXML verwenden. 0132149184, Java Software-Lösungen, Komplettes Buch voller Fallstudien zu Business-Lösungen und Design-Konzepten beim Erstellen geschäftskritischer Geschäftsanwendungen. 'in dem Beispiel – BeniBela

4

Ihre xml Unter der Annahme, in den Variablen ist $books Sie auf eine neue Zeile eine CSV-Datei mit jedem Buch Knoten erstellen könnten mit dieser:

declare function local:my-replace($input) { 
    for $i in $input 
    return '"' || replace($i, '"', '""') || '"' 
}; 
for $book in $books//book 
return string-join(local:my-replace(($book/@isbn, $book/title, $book/description)), ",") || '&#xa;' 

string-join verkettet die verschiedenen Saiten, die lokale Funktion my-replace die Werte ersetzt in die Reihenfolge nach Ihrer Spezifikation.

+0

Das obige Snippet, das Sie veröffentlicht haben, funktioniert im Normalfall sehr gut, aber in CSV werden Felder durch ein Komma (,) getrennt. Wenn nun ein Text selbst ein Komma enthält, interpretiert Excel dieses Komma als Trennzeichen, wenn dieses Komma Teil des Textes ist, beispielsweise ein Teil der Beschreibungszelle oder der Titelzelle. Ein typischer Ansatz ist, Kommas zu entkommen, indem Sie doppelte Anführungszeichen (") umbrechen und doppelte Anführungszeichen durch doppelte Anführungszeichen entfernen: Hallo, Welt von" Ms-Excel "wird sein:" Hallo, Welt von "" Frau -Excel "" ". Wie Sie diesem Weg entkommen? Danke für Ihre große Hilfe. –

+0

Ich habe gerade meine Antwort bearbeitet, um die von Ihnen hinzugefügte Spezifikation widerzuspiegeln. Ich habe gerade eine benutzerdefinierte Funktion my-replace erstellt, die ein" am Anfang und das Ende jedes Elements und ersetzt "mit". – dirkk