xml xslt csv

XML a CSV con XSLT



(4)

Tengo el siguiente documento XML:

<projects> <project> <name>Shockwave</name> <language>Ruby</language> <owner>Brian May</owner> <state>New</state> <startDate>31/10/2008 0:00:00</startDate> </project> <project> <name>Other</name> <language>Erlang</language> <owner>Takashi Miike</owner> <state> Canceled </state> <startDate>07/11/2008 0:00:00</startDate> </project> ...

Y me gustaría obtener esto del resultado de la transformación (XSLT):

Shockwave,Ruby,Brian May,New,31/10/2008 0:00:00 Other,Erlang,Takashi Miike,Cancelled,07/11/2008 0:00:00

¿Alguien sabe el XSLT para lograr esto? Estoy usando .net en caso de que eso importe.

¡Gracias!


Aquí hay una versión con parámetros configurables que puede configurar programáticamente:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="utf-8" /> <xsl:param name="delim" select="'',''" /> <xsl:param name="quote" select="''&quot;''" /> <xsl:param name="break" select="''&#xA;''" /> <xsl:template match="/"> <xsl:apply-templates select="projects/project" /> </xsl:template> <xsl:template match="project"> <xsl:apply-templates /> <xsl:if test="following-sibling::*"> <xsl:value-of select="$break" /> </xsl:if> </xsl:template> <xsl:template match="*"> <!-- remove normalize-space() if you want keep white-space at it is --> <xsl:value-of select="concat($quote, normalize-space(), $quote)" /> <xsl:if test="following-sibling::*"> <xsl:value-of select="$delim" /> </xsl:if> </xsl:template> <xsl:template match="text()" /> </xsl:stylesheet>


Considere ignorar la capa adicional (XSLT) y usar su lenguaje de programación .NET directamente.

La fuerza de XSLT está más en convertir un XML en otro formato XML.


Encontré una hoja de estilos de transformación XML here (el sitio mismo está en alemán)

La hoja de estilo agregada aquí podría ser útil:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="iso-8859-1"/> <xsl:strip-space elements="*" /> <xsl:template match="/*/child::*"> <xsl:for-each select="child::*"> <xsl:if test="position() != last()">"<xsl:value-of select="normalize-space(.)"/>", </xsl:if> <xsl:if test="position() = last()">"<xsl:value-of select="normalize-space(.)"/>"<xsl:text>&#xD;</xsl:text> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>

Quizás desee eliminar las comillas dentro de las etiquetas xsl: if para que no coloque sus valores en comillas, dependiendo de dónde desee usar el archivo CSV.


Esta xsl:stylesheet puede usar una lista especificada de encabezados de columna y asegurará que las filas se ordenarán correctamente.

<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:csv="csv:csv"> <xsl:output method="text" encoding="utf-8" /> <xsl:strip-space elements="*" /> <xsl:variable name="delimiter" select="'',''" /> <csv:columns> <column>name</column> <column>sublease</column> <column>addressBookID</column> <column>boundAmount</column> <column>rentalAmount</column> <column>rentalPeriod</column> <column>rentalBillingCycle</column> <column>tenureIncome</column> <column>tenureBalance</column> <column>totalIncome</column> <column>balance</column> <column>available</column> </csv:columns> <xsl:template match="/property-manager/properties"> <!-- Output the CSV header --> <xsl:for-each select="document('''')/*/csv:columns/*"> <xsl:value-of select="."/> <xsl:if test="position() != last()"> <xsl:value-of select="$delimiter"/> </xsl:if> </xsl:for-each> <xsl:text>&#xa;</xsl:text> <!-- Output rows for each matched property --> <xsl:apply-templates select="property" /> </xsl:template> <xsl:template match="property"> <xsl:variable name="property" select="." /> <!-- Loop through the columns in order --> <xsl:for-each select="document('''')/*/csv:columns/*"> <!-- Extract the column name and value --> <xsl:variable name="column" select="." /> <xsl:variable name="value" select="$property/*[name() = $column]" /> <!-- Quote the value if required --> <xsl:choose> <xsl:when test="contains($value, ''&quot;'')"> <xsl:variable name="x" select="replace($value, ''&quot;'', ''&quot;&quot;'')"/> <xsl:value-of select="concat(''&quot;'', $x, ''&quot;'')"/> </xsl:when> <xsl:when test="contains($value, $delimiter)"> <xsl:value-of select="concat(''&quot;'', $value, ''&quot;'')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$value"/> </xsl:otherwise> </xsl:choose> <!-- Add the delimiter unless we are the last expression --> <xsl:if test="position() != last()"> <xsl:value-of select="$delimiter"/> </xsl:if> </xsl:for-each> <!-- Add a newline at the end of the record --> <xsl:text>&#xa;</xsl:text> </xsl:template> </xsl:stylesheet>