XML到CSV使用XSLT
我有以下的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> ...
我想从转换(XSLT)结果中得到这个:
Shockwave,Ruby,Brian May,New,31/10/2008 0:00:00 Other,Erlang,Takashi Miike,Cancelled,07/11/2008 0:00:00
有谁知道XSLT来实现这一目标? 万一有问题,我正在使用.net。
谢谢!
在这里找到一个XML转换样式表(网站本身是德文的)
这里添加的样式表可能会有帮助:
<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>
也许你想删除xsl:if标签内的引号,这样就不会把你的值放到引号中,这取决于你想要使用CSV文件的位置。
这是一个可配置参数的版本,您可以通过编程来设置:
<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="'"'" /> <xsl:param name="break" select="'
'" /> <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>
这个xsl:stylesheet
可以使用指定的列标题列表,并确保行将被正确排序。
<?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>
</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, '"')"> <xsl:variable name="x" select="replace($value, '"', '""')"/> <xsl:value-of select="concat('"', $x, '"')"/> </xsl:when> <xsl:when test="contains($value, $delimiter)"> <xsl:value-of select="concat('"', $value, '"')"/> </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>
</xsl:text> </xsl:template> </xsl:stylesheet>
考虑忽略附加层(XSLT)并直接使用.NET编程语言。
XSLT的优势在于将一个XML转换成另一个XML格式。