2013-11-25 124 views
1

我使用升壓序列化的持久性,並且由於庫沒有保存到舊版本的存檔/數據結構的構想表示支持,不過,我覺得我給XSLT &根據需要,XPath將新版本轉換爲舊版本。 (這也是我第一次參與XSLT & XPath/XQuery,因此請原諒任何明顯的錯誤)。但是,我已經完成了大約一半的工作,但似乎無法完成它(這也是我的第一次嘗試進入XSLT & XPath/XQuery,請原諒任何明顯的錯誤)。XSLT轉換

這裏是我的出發XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<!DOCTYPE boost_serialization> 
<boost_serialization signature="serialization::archive" version="7"> 
<tester class_id="0" tracking_level="0" version="0"> 
    <count>2</count> 
    <item_version>0</item_version> 
    <item class_id="2" class_name="CLASS_D" tracking_level="0" version="0"> 
     <A class_id="1" tracking_level="1" version="0" object_id="_0"> 
      <pimpl class_id="3" tracking_level="1" version="0" object_id="_1"> 
       <b>1</b> 
      </pimpl> 
     </A> 
     <pimpl class_id="4" tracking_level="1" version="0" object_id="_2"> 
      <c>2</c> 
     </pimpl> 
    </item> 
    <item class_id="5" class_name="CLASS_E" tracking_level="0" version="0"> 
     <A object_id="_3"> 
      <pimpl class_id_reference="3" object_id="_4"> 
       <b>1</b> 
      </pimpl> 
     </A> 
     <pimpl class_id="6" tracking_level="1" version="0" object_id="_5"> 
      <f>2</f> 
     </pimpl> 
    </item> 
</tester> 
</boost_serialization> 

我想要做的,是帶有屬性CLASS_NAME =「CLASS_E」要像CLASS_NAME =「CLASS_D」的項目改造項目,但我需要離開單獨的object_id屬性。

這就是我想要的:

<?xml version="1.0" encoding="utf-8"?> 
<boost_serialization signature="serialization::archive" version="7"> 
    <tester class_id="0" tracking_level="0" version="0"> 
    <count>2</count> 
    <item_version>0</item_version> 
    <item class_id="2" class_name="CLASS_D" tracking_level="0" version="0"> 
     <A class_id="1" tracking_level="1" version="0" object_id="_0"> 
     <pimpl class_id="3" tracking_level="1" version="0" object_id="_1"> 
      <b>1</b> 
     </pimpl> 
     </A> 
     <pimpl class_id="4" tracking_level="1" version="0" object_id="_2"> 
     <c>2</c> 
     </pimpl> 
    </item> 
    <item class_name="CLASS_D" class_id="2" tracking_level="0" version="0"> 
     <A object_id="_3"> 
     <pimpl class_id_reference="3" object_id="_4"> 
      <b>1</b> 
     </pimpl> 
     </A> 
     <pimpl class_id="4" tracking_level="1" version="0" object_id="_5"> 
     <c>2</c> 
     </pimpl> 
    </item> 
    </tester> 
</boost_serialization> 

這是模板我到目前爲止:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" omit-xml-declaration="no" encoding="UTF-8" indent="yes"/> 

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

    <!-- replace attribute class_name value with another--> 
    <!-- replace attribute class_id value with another--> 
    <!-- only on this node!--> 
    <!-- could call another template to change more nested things--> 
    <xsl:template match="item/@class_name[. = 'CLASS_E']"> 
    <xsl:attribute name="class_name">CLASS_D</xsl:attribute> 
    <xsl:attribute name="class_id">2</xsl:attribute> 
    </xsl:template> 

</xsl:stylesheet> 

我不知道如何繼續編輯項目的子節點我與此行匹配: 因爲我需要將「f」節點更改爲「c」並將pimpl「class_id」從6更改爲4

在此先感謝

回答

1

你剛纔匹配的產品屬性,因此沒有子節點!父節點將已通過身份模板,所以要「繼續」編輯匹配的,只是有一個匹配的模板類標識碼屬性要匹配,但包括在XPath表達式相關項目匹配。

例如,改變平普爾元素的類標識碼,添加這個模板

<xsl:template match="item[@class_name = 'CLASS_E']/pimpl/@class_id"> 
    <xsl:attribute name="class_id">4</xsl:attribute> 
</xsl:template> 

而改變˚F元素中,添加這個模板

<xsl:template match="item[@class_name = 'CLASS_E']/pimpl/f"> 
    <c> 
     <xsl:apply-templates select="@*|node()"/> 
    </c> 
</xsl:template> 

記住,該匹配適用於輸入文檔,因此在輸出文檔中將「CLASS_E」更改爲「CLASS_D」並不重要。

請注意,您的當前模板可能與class_name屬性相匹配。在此,您將用兩個屬性替換它,其中包括已存在的class_id屬性。 XSLT將替換輸出樹中具有相同名稱的屬性已被輸出。這意味着如果你的XML看起來像這樣...

<item class_name="CLASS_E" class_id="5" tracking_level="0" version="0"> 

然後將輸出實際上看這本

<item class_name="CLASS_D" class_id="5" tracking_level="0" version="0"> 

這是因爲身份模板匹配模板後類標識碼屬性的CLASS_NAME匹配,因此將取代class_id屬性,它是當前匹配的屬性。

但削減長話短說,試試這個XSLT .....

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" omit-xml-declaration="no" encoding="UTF-8" indent="yes"/> 

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

    <xsl:template match="item/@class_name[. = 'CLASS_E']"> 
    <xsl:attribute name="class_name">CLASS_D</xsl:attribute> 
    </xsl:template> 

    <xsl:template match="item[@class_name = 'CLASS_E']/@class_id"> 
    <xsl:attribute name="class_id">2</xsl:attribute> 
    </xsl:template> 

    <xsl:template match="item[@class_name = 'CLASS_E']/pimpl/@class_id"> 
    <xsl:attribute name="class_id">4</xsl:attribute> 
    </xsl:template> 

    <xsl:template match="item[@class_name = 'CLASS_E']/pimpl/f"> 
    <c> 
     <xsl:apply-templates select="@*|node()"/> 
    </c> 
    </xsl:template> 
</xsl:stylesheet> 
+0

謝謝你這麼多的詳細答覆。這有助於爲我解決很多問題。 – Jeremy