2011-04-04 47 views
0

我這裏有一個XML文件轉換複雜的XML爲csv ...使用XSL使用循環功能

<?xml version="1.0" encoding="utf-8" ?> 

<!DOCTYPE dependencies SYSTEM "http://depfind.sourceforge.net/dtd/dependencies.dtd"> 

<dependencies> 
    <package confirmed="yes"> 
     <name>com.infopro.Dependency</name> 
     <class confirmed="yes"> 
      <name>com.infopro.Dependency.A</name> 
      <outbound type="class" confirmed="no">java.lang.Object</outbound> 
      <outbound type="class" confirmed="no">javax.ejb.Stateless</outbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.a</inbound> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.A.A()</name> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.A.b</outbound> 
       <outbound type="class" confirmed="yes">com.infopro.Dependency.B</outbound> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</outbound> 
       <outbound type="feature" confirmed="no">java.lang.Object.Object()</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.A.b</name> 
       <outbound type="class" confirmed="yes">com.infopro.Dependency.B</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.A.check(java.lang.String, java.lang.String)</name> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.A.stat</outbound> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.doStatus()</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.A.doStatus()</name> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.A.check(java.lang.String, java.lang.String)</outbound> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.A.name</outbound> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.A.user_id</outbound> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.A.name</name> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.doStatus()</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.A.stat</name> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.check(java.lang.String, java.lang.String)</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.A.user_id</name> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.doStatus()</inbound> 
      </feature> 
     </class> 
     <class confirmed="yes"> 
      <name>com.infopro.Dependency.B</name> 
      <outbound type="class" confirmed="yes">com.infopro.Dependency.C</outbound> 
      <outbound type="class" confirmed="no">java.lang.Object</outbound> 
      <outbound type="class" confirmed="no">javax.ejb.Stateless</outbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.b</inbound> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.B.B()</name> 
       <outbound type="class" confirmed="yes">com.infopro.Dependency.A</outbound> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</outbound> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.B.a</outbound> 
       <outbound type="feature" confirmed="no">java.lang.Object.Object()</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.B.a</name> 
       <outbound type="class" confirmed="yes">com.infopro.Dependency.A</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.B.check(java.lang.String, java.lang.String)</name> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.B.stat</outbound> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.doStatus()</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.B.doStatus()</name> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.B.check(java.lang.String, java.lang.String)</outbound> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.B.name</outbound> 
       <outbound type="feature" confirmed="yes">com.infopro.Dependency.B.user_id</outbound> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.B.name</name> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.doStatus()</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.B.stat</name> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.check(java.lang.String, java.lang.String)</inbound> 
      </feature> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.B.user_id</name> 
       <outbound type="class" confirmed="no">java.lang.String</outbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.doStatus()</inbound> 
      </feature> 
     </class> 
     <class confirmed="yes"> 
      <name>com.infopro.Dependency.C</name> 
      <outbound type="class" confirmed="no">java.lang.Object</outbound> 
      <outbound type="class" confirmed="no">javax.ejb.Remote</outbound> 
      <inbound type="class" confirmed="yes">com.infopro.Dependency.B</inbound> 
      <feature confirmed="yes"> 
       <name>com.infopro.Dependency.C.doStatus()</name> 
      </feature> 
     </class> 
    </package> 
    <package confirmed="no"> 
     <name>java.lang</name> 
     <class confirmed="no"> 
      <name>java.lang.Object</name> 
      <inbound type="class" confirmed="yes">com.infopro.Dependency.A</inbound> 
      <inbound type="class" confirmed="yes">com.infopro.Dependency.B</inbound> 
      <inbound type="class" confirmed="yes">com.infopro.Dependency.C</inbound> 
      <feature confirmed="no"> 
       <name>java.lang.Object.Object()</name> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</inbound> 
       <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</inbound> 
      </feature> 
     </class> 
     <class confirmed="no"> 
      <name>java.lang.String</name> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.check(java.lang.String, java.lang.String)</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.doStatus()</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.name</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.stat</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.A.user_id</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.check(java.lang.String, java.lang.String)</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.doStatus()</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.name</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.stat</inbound> 
      <inbound type="feature" confirmed="yes">com.infopro.Dependency.B.user_id</inbound> 
     </class> 
    </package> 
    <package confirmed="no"> 
     <name>javax.ejb</name> 
     <class confirmed="no"> 
      <name>javax.ejb.Remote</name> 
      <inbound type="class" confirmed="yes">com.infopro.Dependency.C</inbound> 
     </class> 
     <class confirmed="no"> 
      <name>javax.ejb.Stateless</name> 
      <inbound type="class" confirmed="yes">com.infopro.Dependency.A</inbound> 
      <inbound type="class" confirmed="yes">com.infopro.Dependency.B</inbound> 
     </class> 
    </package> 
</dependencies> 

我要創建這種格式的csv文件的輸出..

classname1, outbound. 

classname1, outbound. 

.    . 

.    . 

classname1, inbound. 

.    . 

.    . 

classname2, outbound. 

.    . 

classname2, inbound. 

和等等。

現在我面臨的挑戰是每個班級的入站和出站的數量是不同的和不同的。所以我必須指定循環。此外,我只需要類名稱包含「com」關鍵字或字符串裏面不包名稱,功能名稱全部。我需要做這個xsl,以便對於所有類似的xml我生成我可以將其更改爲csv表格爲我進一步的數據,我需要的過程。

在xsl我創建如下所示,但我STIL面臨着一些缺陷和問題

<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="class[contains(.//text(), 'com')]"> 
     <xsl:text></xsl:text><xsl:value-of select="name"/><xsl:if test="@confirmed='no'"> *</xsl:if><xsl:text> </xsl:text> 
     <xsl:for-each select="outbound[contains(.//text(), 'com')]"> 
      <xsl:text disable-output-escaping="yes"> , </xsl:text><xsl:value-of select="."/><xsl:if test="@confirmed='no'"> *</xsl:if><xsl:text> 
</xsl:text> 
     </xsl:for-each> 
     <xsl:for-each select="inbound[contains(.//text(), 'com')]"> 
      <xsl:text disable-output-escaping="yes"> , </xsl:text><xsl:value-of select="."/><xsl:if test="@confirmed='no'"> *</xsl:if><xsl:text> 
</xsl:text> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

和輸出作爲

com.infopro.Dependencycom.infopro.Dependency.A        , com.infopro.Dependency.B.B() 
                      , com.infopro.Dependency.B.a 
com.infopro.Dependency.B              , com.infopro.Dependency.C 
                      , com.infopro.Dependency.A.A() 
                      , com.infopro.Dependency.A.b 
com.infopro.Dependency.C              , com.infopro.Dependency.B 
java.langjava.lang.Objectcom.infopro.Dependency.Acom.infopro.Dependency.Bcom.infopro.Dependency.Cjava.lang.Object.Object()com.infopro.Dependency.A.A()com.infopro.Dependency.B.B()java.lang.Stringcom.infopro.Dependency.A.check(java.lang.String, java.lang.String)com.infopro.Dependency.A.doStatus()com.infopro.Dependency.A.namecom.infopro.Dependency.A.statcom.infopro.Dependency.A.user_idcom.infopro.Dependency.B.check(java.lang.String, java.lang.String)com.infopro.Dependency.B.doStatus()com.infopro.Dependency.B.namecom.infopro.Dependency.B.statcom.infopro.Dependency.B.user_idjavax.ejbjavax.ejb.Remotecom.infopro.Dependency.Cjavax.ejb.Statelesscom.infopro.Dependency.Acom.infopro.Dependency.B 

狀排列的表幾乎發生,但具有包名稱問題仍然來堅持一流的名字,並在最後一些不必要的java字符串串。 希望得到指導和幫助。謝謝

+0

我有問題完全顯示我的xsl。我試圖完全粘貼它,但它只是部分。對此而言。 – Memoc 2011-04-04 03:09:22

+0

你可以縮進所有的代碼4個空格 - 在編輯器中使用'{}'按鈕來做到這一點。我爲你修好了。 – 2011-04-04 03:34:05

+0

您的輸出不清楚。提供一些與您提供的輸入相匹配的輸出。 – 2011-04-04 03:36:06

回答

2

那麼,你不必做任何明確的循環。你可以做你想用模板做的所有事情。

要有效編寫XSLT,您必須考慮轉換。想一想,「我想把輸入中的某些東西轉換成輸出中的某些東西。」那些東西是什麼?你沒有在你的問題中闡述他們,你可能沒有在你的設計中闡述他們。

看來你想要的是將每個package元素轉換爲輸出中的一行。所以你需要一個模板。每行的第一件事是包名(即name元素的文本內容),最後一件事是換行符。所以用這個啓動:

<xsl:template match="/"> 
    <xsl:apply-templates select="dependencies/package"/> 
</xsl:template> 

<xsl:template match="package"> 
    <xsl:value-of select="name/text()"/> 
    <!-- something will go in here --> 
    <xsl:text>&#x0a;</xsl:text> 
</xsl:template> 

如果你運行你的輸入文檔中變換,(假設你已經把它變成一個實際的樣式表),你應該得到所有的包名作爲輸出的一個簡單的列表。

現在您想要將outboundinbound元素的內容添加爲每行上額外的以逗號分隔的元素。什麼是轉型?如果confirmed屬性等於no,則這些元素中的每一個都需要轉換爲包含逗號,元素文本內容和星號的文本。

這很容易實現:只需創建一個模板這些元素,並將其應用於package模板中。

<xsl:template match="package"> 
    <xsl:value-of select="name/text()"/> 
    <xsl:apply-templates select="output[contains(text(), '.com')]"/> 
    <xsl:apply-templates select="input[contains(text(), '.com')]"/> 
    <xsl:text>&#x0a;</xsl:text> 
</xsl:template> 

<xsl:template match="output|input"> 
    <xsl:text>, </xsl:text> 
    <xsl:value-of select="text()"/> 
    <xsl:if test="@confirmed='no'"> 
     <xsl:text> *</xsl:text> 
    </xsl:text> 
</xsl:text> 

兩件事情是關於這個方法來設計和實施重要的:首先,你使用模板來改變既然你只需要其文本內容與con.開始出現的元素,應用模板時添加謂詞節點,而不是嘗試使用不是爲其設計的語言使用過程式編程。

其次,你只是在轉換你明確選擇的節點。現在,在輸出結束時得到垃圾的原因是,您已經將模板應用於您認爲不應用於它們的節點:您沒有創建應用於文檔根目錄的模板,並且所以XSLT處理器將內置模板應用到它找到的每個元素。

+0

+1以獲得很好的答案。 – 2011-04-04 13:09:00

+0

+1與OP呆在一起,直到最後一段... – 2011-04-04 13:49:23