2013-01-17 21 views
0

我有一個這樣的XSLT施加:XSLT變化/上覆蓋屬性複製的不(使用撒克遜)

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:db="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="/">  
     <xsl:for-each select="db:databaseChangeLog/db:changeSet"> 
      <xsl:if test="name(*[1])='createTable'"> 
      <xsl:result-document href="base/tables/{position()}_{name(*[1])}_{*[1]/@tableName}.xml"> 
      <databaseChangeLog 
       xmlns="http://www.liquibase.org/xml/ns/dbchangelog" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> 

       <xsl:copy-of select="."/>      

       <xsl:copy-of select="../db:changeSet[name(*[1])='createIndex' and *[1]/@tableName= current()/*[1]/@tableName ]" /> 

      </databaseChangeLog> 
     </xsl:result-document>  
     </xsl:if> 
     </xsl:for-each>  
    </xsl:template> 

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

    <xsl:template match="db:changeSet/@author" mode="copy"> 
     <xsl:attribute name="author"> 
      <xsl:value-of select="'sakhunzai'"/> 
     </xsl:attribute> 
    </xsl:template> 

</xsl:stylesheet> 

XML部分文件

<changeSet author="xxx (generated)" id="1358259674512-26"> 
     <createIndex indexName="category_id" tableName="teams" unique="false"> 
      <column name="audience_id"/> 
     </createIndex> 
</changeSet> 
<changeSet author="xxx (generated)" id="1358259674512-29"> 
    <createIndex indexName="id" tableName="users" unique="false"> 
     <column name="id"/> 
     <column name="career_lead_id"/> 
    </createIndex> 
</changeSet> 

我要重寫的屬性值changeSet(作者和ID)。請幫我修復xslt。

一切工作正常,但@author atrribute值不會在目標XML文件更改 注:由於在xsltproc做不到的事情,我切換到撒克遜基於java的處理器如

java -jar /usr/local/liquibase/saxon/saxon9he.jar common.xml table.xslt

工作XSLT

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:db="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="/">  
     <xsl:for-each select="db:databaseChangeLog/db:changeSet[db:createTable]"> 
      <xsl:result-document href="base/tables/{position()}_{name(*[1])}_{*[1]/@tableName}.xml"> 
      <databaseChangeLog 
       xmlns="http://www.liquibase.org/xml/ns/dbchangelog" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> 

       <xsl:apply-templates select="." mode="copy"/>      

       <xsl:apply-templates select="../db:changeSet[db:createIndex and *[1]/@tableName= current()/*[1]/@tableName ]" mode="copy"/> 

      </databaseChangeLog> 
     </xsl:result-document> 
     </xsl:for-each>  
    </xsl:template> 

    <xsl:template match="node()" mode="copy"> 
     <xsl:copy> 
      <xsl:attribute name="author">sakhunzai</xsl:attribute> 
      <xsl:copy-of select="@id|node()"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

回答

1

<xsl:copy-of />不會導致應用模板。它只是創建一個精確的副本。如何改變這一行

<xsl:template match="db:changeSet/@author"> 

這樣:

<xsl:template match="db:changeSet/@author" mode="copy"> 

添加這個模板:

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

終於改變這一點:

<xsl:copy-of select="../db:changeSet[name(*[1])='createIndex' and *[1]/@tableName= current()/*[1]/@tableName ]"> 
    <xsl:copy-of select="."/>      
</xsl:copy-of> 

要這樣:

<xsl:apply-templates 
    select=="../db:changeSet[name(*[1])='createIndex' and *[1]/@tableName = current()/*[1]/@tableName]" 
    mode="copy" /> 

作爲邊注,這看起來有點冗餘:

<xsl:copy-of select="current()[name()='changeSet']">       
    <xsl:copy-of select="."/> 
</xsl:copy-of> 

當前節點必須具有名稱「變更」,憑藉for-each循環的。我相信這應該能滿足那部分:

<xsl:copy-of select="." /> 

完全XSLT:

<xsl:stylesheet xmlns:db="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="/">  
     <xsl:for-each select="db:databaseChangeLog/db:changeSet"> 
      <xsl:if test="name(*[1])='createTable'"> 
      <xsl:document href="base/tables/{position()}_{name(*[1])}_{*[1]/@tableName}.xml"> 
      <databaseChangeLog 
       xmlns="http://www.liquibase.org/xml/ns/dbchangelog" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> 

        <xsl:copy-of select="." />       

        <xsl:apply-templates select="../db:changeSet[name(*[1])='createIndex' and *[1]/@tableName= current()/*[1]/@tableName ]" mode="copy" /> 
      </databaseChangeLog> 
     </xsl:document>  
     </xsl:if> 
     </xsl:for-each>  
    </xsl:template> 

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

    <xsl:template match="db:changeSet/@author" mode="copy"> 
    <xsl:attribute name="author"> 
     <xsl:value-of select="'sakhunzai'"/> 
     </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

我不認爲XSLT可以像下面進一步提高。請嘗試如果你喜歡:

<xsl:stylesheet xmlns:db="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="db:changeSet" /> 

    <xsl:template match="db:changeSet[db:createTable]"> 
    <xsl:document href="base/tables/{position()}_{name(*[1])}_{*[1]/@tableName}.xml"> 
     <databaseChangeLog 
      xmlns="http://www.liquibase.org/xml/ns/dbchangelog" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> 

     <xsl:copy-of select="." /> 

     <xsl:apply-templates select="../db:changeSet[db:createIndex and *[1]/@tableName = current()/*[1]/@tableName ]" mode="copy" /> 
     </databaseChangeLog> 
    </xsl:document> 
    </xsl:template> 

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

    <xsl:template match="db:changeSet/@author" mode="copy"> 
    <xsl:attribute name="author"> 
     <xsl:value-of select="'sakhunzai'"/> 
    </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 
+0

請問您是否可以在答案的最後加上修改後的完整xslt。我只是混淆了修改的位置 – sakhunzai

+0

添加了完整的XSLT。 – JLRishe

+0

我按照你的建議修復了xslt,但是@mode沒有與撒克遜工作(對不起,我切換到撒克遜)請檢查我的編輯 – sakhunzai

1

xsl:copy-of元素不允許子元素。它看起來像xsltproc沒有足夠小心地驗證你的樣式表。

+0

是的,你是對的我現在正在使用撒克遜,檢查我的更新xslt和xml文件 – sakhunzai

+0

對不起,我討厭編輯的問題。它是否仍然存在問題讓人很不清楚,如果是的話,它是什麼。如果您仍有問題,請開始新的話題。 –