xslt csv

XML a CSV usando la ayuda de XSLT



(2)

Creo que necesita una solución recursiva para abordar este problema. Entonces, necesitarías algo que siga sumergiéndose en el árbol hasta que llegue a un nodo de texto (). Si ese nodo de texto () es realmente un elemento secundario del último nodo, coloca una nueva línea. De lo contrario, solo pone el valor con una coma.

Si el nodo no tiene un nodo de texto () como su hijo, entonces comienza recursivamente a cavar en ese árbol.

<xsl:strip-space elements="*" /> <xsl:template name="rec"> <xsl:param name="node"/> <xsl:for-each select="child::*"> <xsl:choose> <xsl:when test="child::text()"> <xsl:choose> <xsl:when test="local-name(.) != ''UpdatedDate''">"<xsl:value-of select="normalize-space(.)"/>", </xsl:when> <xsl:otherwise>"<xsl:value-of select="normalize-space(.)"/>" <xsl:text>&#xD;</xsl:text></xsl:otherwise> </xsl:choose> </xsl:when> <xsl:when test="child::node()"> <xsl:call-template name="rec"> <xsl:with-param name="node" select="child::node()"/> </xsl:call-template> </xsl:when> </xsl:choose> </xsl:for-each> </xsl:template>

Esto no es a prueba de tontos, pero produjo este resultado por mi parte con Saxon:

"127.0.0.1", "[email protected]", "Internet Corporation for Assigned Names and Number", "+1-310-301-5820", "...", "4676 Admiralty Way, Suite 330", "Marina del Rey", "US", "Internet Assigned Numbers Authority", "90292-6695", "CA", "[email protected]", "Internet Corporation for Assigned Names and Number", "+1-310-301-5820", "2010-04-14"

Espero que esto ayude.

Me gustaría convertir XML en CSV utilizando un XSLT, pero cuando se aplica el XSL desde el hilo SO titulado XML To CSV XSLT contra mi entrada:

<WhoisRecord> <DomainName>127.0.0.1</DomainName> <RegistryData> <AbuseContact> <Email>[email protected]</Email> <Name>Internet Corporation for Assigned Names and Number</Name> <Phone>+1-310-301-5820</Phone> </AbuseContact> <AdministrativeContact i:nil="true"/> <BillingContact i:nil="true"/> <CreatedDate/> <RawText>...</RawText> <Registrant> <Address>4676 Admiralty Way, Suite 330</Address> <City>Marina del Rey</City> <Country>US</Country> <Name>Internet Assigned Numbers Authority</Name> <PostalCode>90292-6695</PostalCode> <StateProv>CA</StateProv> </Registrant> <TechnicalContact> <Email>[email protected]</Email> <Name>Internet Corporation for Assigned Names and Number</Name> <Phone>+1-310-301-5820</Phone> </TechnicalContact> <UpdatedDate>2010-04-14</UpdatedDate> <ZoneContact i:nil="true"/> </RegistryData> </WhoisRecord>

Termino con:

[email protected] Corporation for Assigned Names and Number+1-310-301-5820, , , , ..., 4676 Admiralty Way, Suite 330Marina del ReyUSInternet Assigned Numbers Authority90292-6695CA, [email protected] Corporation for Assigned Names and Number+1-310-301-5820, 2010-04-14,

Mi problema es que a la transformación resultante le faltan nodos (como el elemento DomainName que contiene la dirección IP) y algunos nodos secundarios se concatenan sin comas (como los elementos secundarios de AbuseContact).

Me gustaría ver todo el resultado XML en formato CSV y cadenas como: "[email protected] Corporation for Assigned Names and Number + 1-310-301-5820", delimitada por comas.

Mi XSL está bastante oxidado. Tu ayuda es apreciada. :)

Aquí está el XSL que estoy usando:

<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> </xsl:text> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>


Esta simple transformación produce el resultado deseado :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <xsl:apply-templates select="//text()"/> </xsl:template> <xsl:template match="text()"> <xsl:copy-of select="."/> <xsl:if test="not(position()=last())">,</xsl:if> </xsl:template> </xsl:stylesheet>

Tenga en cuenta el uso de:

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

descartar cualquier nodo de texto de espacio en blanco solamente.

Actualización : AJ planteó el problema de que los resultados deberían agruparse en recirds / tuplas por línea. No se define en la pregunta qué debe ser exactamente un registro / tupla. Por lo tanto, la solución actual resuelve los dos problemas de los nodos de texto de espacio en blanco y de las comas que faltan, pero no apunta a generar la salida en registros / tuplas.