2012-09-28 45 views
0

我將與代碼開始 - 我們都喜歡代碼:dXSLT - 偷偷摸摸插入(XSL:複製)

XML:

<report> 
     <subject> 
      <subjectId>1</subjectId> 
      <name>John</name> 
      <surname>Doe</surname> 
     </subject> 
     <subject> 
      <subjectId>2</subjectId> 
      <name>Frank</name> 
      <surname>Timothy</surname> 
     </subject> 
     <individual> 
      <individualId>10</individualId> 
      <name>Isaac</name> 
      <surname>Newton</surname> 
      <co-worker> 
       <subject> 
        <subjectId>1</subjectId> 
        <inXml>true</inXml> 
       </subject> 
       <subject> 
        <subjectId>2</subjectId> 
        <inXml>true</inXml> 
       </subject> 
      </co-worker> 
     </individual> 

     <owner> 
      <subject> 
       <subjectId>2</subjectId> 
       <inXml>true</inXml> 
      </subject> 
      <share>100</share> 
     </owner> 

     <individual> 
      <individualId>10</individualId> 
      <inXml>true</inXml> 
     </individual> 
    </report> 

XML 2:

<report> 
     <owner> 
      <individual> 
       <individualId>10</individualId> 
       <inXml>true</inXml> 
      </individual> 
     </owner> 
     <individual> 
      <individualId>2</individualId> 
      <name>John</name> 
      <surname>Doe</surname> 
      <co-worker> 
       <individual> 
        <individualId>10</individualId> 
        <inXml>true</inXml> 
       </individual> 
      </co-worker> 
     </individual> 
     <individual> 
      <individualId>10</individualId> 
      <name>Isaac</name> 
      <surname>Newton</surname> 
      <co-worker> 
       <individual> 
        <individualId>2</individualId> 
        <inXml>true</inXml> 
       </individual> 
      </co-worker> 
     </individual> 

    </report> 

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> 
     <xsl:output method="xml" indent="yes" /> 

     <xsl:template match="individual[inXml='true']"> 
      <xsl:variable name="indId" select="./individualId/text()" /> 
      <xsl:variable name="result" select="//individual[not(inXml) and individualId=$indId]/*" /> 
      <xsl:choose> 
       <xsl:when test="$result != ''"> 
        <xsl:copy> 
         <xsl:apply-templates select="$result" /> 
        </xsl:copy> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:copy-of select="." /> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:template> 

     <xsl:template match="subject[inXml='true']"> 
      <xsl:variable name="subId" select="./subjectId/text()" /> 
      <xsl:variable name="result" select="//subject[not(inXml) and subjectId=$subId]/*" /> 
      <xsl:choose> 
       <xsl:when test="$result != ''"> 
        <xsl:copy> 
         <xsl:apply-templates select="$result" /> 
        </xsl:copy> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:copy-of select="." /> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:template> 

     <xsl:template match="@* | node()"> 
      <xsl:copy> 
       <xsl:apply-templates select="@* | node()" /> 
      </xsl:copy> 
     </xsl:template> 

    </xsl:stylesheet> 

什麼我試着來實現? - 我想在「inXml」標籤出現的地方複製主題/個人。 XSLT似乎工作..但稍大的xmls ..大約1MB(這不是很大..) 我的Java應用程序失敗,java.lang.OutOfMemoryError:Java堆空間。 我將文件重定向到文件..令人驚訝的是 - 轉換結果文件隨着光速增長 - 大約300mb後15秒! :D hehehe - 這證明我的xlst中一定有一些錯誤,導致無限循環。

什麼是重要的 - 而節點的複製可能發生已經有「inXml」內 - 這就是爲什麼我申請的模板或結果。我準備的XML描述了這個問題。

編輯: XML2很可能完全搞砸了我的申請。我該如何解決它?我希望通過XSLT解決我的jaxb unmarshalling問題 - 這不是我所知道的解決方案 - 我需要在解組過程中插入對象的引用,而不是嘗試在其中插入更多XML節點。我怎樣才能做到這一點?

預先感謝您!

+0

在您的文章中XML和XSL對我的作品與xsltproc的運行。 –

+0

像我說的..它在小文件中的作品。在大的它倒塌; -/ –

+0

考慮發佈一個最小但完整的文件,其中轉換失敗。您是否嘗試增加允許由Java JRE分配的內存?你使用哪種Java XSLT處理器?如果數據結構是遞歸的,並且apply-templates被一次又一次地調用,那麼我也會期望堆棧溢出,而不一定是內存不足錯誤。當你轉換成文件時,你會看到結果不斷增加,你是否中止了轉換或者在一段時間後完成了轉換? –

回答

0

您的代碼將進入無限遞歸如果在你的數據的週期。

我懷疑條件not(inXml)not(inXML='true')防止這種情況;但不知道你的數據,我不能確定。

+0

謝謝你的回答。 not(inXml)是來自模式的條件 - 無論是「完整數據+ ID」還是「inXml + id」 - 不是(inXml ='true')都會減慢進程速度。 –

+0

我認爲XML2正在描述可能在我的文件中發生的循環。我怎麼解決這個問題? –

+0

@MironBe,當我有空時,我會盡量找到一個可以接受的解決方案。很明顯,XSLT 2.0是解決此任務的更好工具,因爲它可以不使用臨時文檔樹來實現中間結果,這可以顯着提高效率 - 無論是在內存中還是在時間上。只需要進行「實用程序」轉換來檢查週期就容易多了 - 您是否對這樣的實用程序以及XSLT 2.0解決方案感興趣? –