2017-05-28 33 views
1

我有以下的XML文件(爲了說明的目的,我在這裏削減了XML和XSLT;在真正的XML文檔中,還有更多的數據I關心,還有很多更多的,我不關心,而且通常有十幾<Document>標籤的順序,並非僅此二人在這裏):從XML轉換爲帶有XSLT 1.0的CSV,變空行

<DocumentList> 
    <Document> 
    <SerialNumber>74631225</SerialNumber> 
    <MailRoomDate>2011-12-27-05:00</MailRoomDate> 
    <DocumentTypeCode>URC</DocumentTypeCode> 
    </Document> 
    <Document> 
    <SerialNumber>74631225</SerialNumber> 
    <MailRoomDate>2011-12-19-05:00</MailRoomDate> 
    <DocumentTypeCode>IPC</DocumentTypeCode> 
    </Document> 
</DocumentList> 

我希望把它變成以逗號分隔的值,每個文檔前後都帶有分隔符行(分別爲BeginRepeatedField和EndRepeatedField),如下所示:

BeginRepeatedField,"Document" 
ApplicationNumber,"74631225" 
MailRoomDate,"2011-12-27-05:00" 
DocumentTypeCode,"URC" 
EndRepeatedField,"Document" 
BeginRepeatedField,"Document" 
ApplicationNumber,"74631225" 
MailRoomDate,"2011-12-19-05:00" 
DocumentTypeCode,"IPC" 
EndRepeatedField,"Document" 

這裏是我的嘗試:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" encoding="utf-8" /> 
<xsl:strip-space elements="*"/> 
<xsl:variable name='NL'><xsl:text>&#10;</xsl:text></xsl:variable><!-- NL = newline character X'0A' --> 
<xsl:template match="Document"> 
BeginRepeatedField,"Document"<xsl:text/> 
ApplicationNumber,"<xsl:value-of select="normalize-space(SerialNumber)"/>"<xsl:text/> 
MailRoomDate,"<xsl:value-of select="normalize-space(MailRoomDate)"/>"<xsl:text/> 
DocumentTypeCode,"<xsl:value-of select="normalize-space(DocumentTypeCode)"/>"<xsl:text/> 
EndRepeatedField,"Document"<xsl:text/> 
</xsl:template> 
</xsl:stylesheet> 

當我使用,我得到的文件的開頭的額外的空行。現在,我問了一個類似的問題在相似背景而回 - One pesky blank line in an XSLT transform - 和運用我學到的東西在那裏,我的模板改變了第一線與<xsl:text/>先於:

<xsl:text/>BeginRepeatedField,"Document"<xsl:text/> 

而這也得到擺脫空白線;然而,當我這樣做,從第一個文件關閉定界符線,並從第二個文檔打開定界符得到級聯:

EndRepeatedField,"Document"BeginRepeatedField,"Document" 

我可以避開通過從最後一行除去<xsl:text/>模板的結尾:

EndRepeatedField,"Document" 

或通過顯式添加新行:

EndRepeatedField,"Document"<xsl:text/><xsl:value-of select='$NL' /> 

而且,我在這兩種情況下,我沒有在文件頂部找到空行,並且我沒有得到那種不需要的連接。但現在我在文件的結尾處得到空行。

我試過的一切都讓我留下了一個不需要的空白行(無論是在頂部還是在底部),否則就會產生不必要的連接。任何解決方案例如,任何方式有條件地除了第一個<Document>之外全部添加新行?

回答

0

<xsl:text/>是一個空的,自閉的元素,它什麼都不做。

要輸出的文字文本,把它xsl:text元素,採用開<xsl:text></xsl:text>標籤 - 例如:

<xsl:template match="Document"> 
<xsl:text>BeginRepeatedField,"Document"</xsl:text> 
... 

你有什麼現在輸出<xsl:template match="Document"><xsl:text/>之間的全部文本節點,包括換行符/ s。

+0

不幸的是,這仍然會產生連接錯誤。 – codingatty

+0

@codingatty您需要在文檔的末尾放置換行符。如果您不希望在最後一個換行符後面出現尾隨換行符,請有條件地執行 - 例如,請參閱:https://stackoverflow.com/questions/21529261/xsl-printing-linebreak-but-leave-out-last -line-break/21584607#21584607 –

0

我可能擁有它。我不確定這是最好的方法,但它似乎工作...

我發現如何有條件地添加換行符。所以我設置的最後一個模板線壓制換行符:

EndRepeatedField,"Document"<xsl:text/> 

,然後添加新行,除非它是最後<Document>

<xsl:if test="position() != last()"> 
    <xsl:value-of select='$NL' /> 
</xsl:if> 

似乎是工作;需要進一步測試。

+0

正如您所做的那樣有條件添加換行符是正確的。使用空的'xsl:text'元素是錯誤的。 –

+0

謝謝;但沒有空的xsl:text元素,在輸出中的每個分隔符行之間插入一個額外的空白行。它可能在美觀上是錯誤的,但它確實使它工作。 你提出了一個真正的好點幾個意見。我發現其他CSV製作程序確實在最後一行包含了換行符,所以我可能會重新考慮這一點,以保持一致;並改變它所接受的程序。我感謝您的幫助。 – codingatty

+0

「*沒有空的xsl:文本元素,在輸出中的每個分隔符行之間插入一個額外的空白行。*」不,如果按照我在答案中所說的內容執行操作,則不行。你正在做的是一個恰巧工作的黑客(並且BTW可以處理任何其他空元素,而不僅僅是'xsl:text')。 –