[英]XSLT transformation of child nodes
我正在使用boost序列化來實現持久性,並且由於該庫不支持保存到較舊版本的歸檔/數據結構的想法,因此盡管我會給XSLT和XPath一個嘗試從新版本轉換的想法根據需要將其版本升級到舊版本。
我已經走了一半,但似乎還沒完成(這也是我第一次涉足XSLT&XPath / XQuery,所以請原諒任何明顯的錯誤)。
這是我的起始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
提前致謝
您剛剛匹配的項目是一個屬性,因此沒有子節點! 父節點將通過身份模板進行匹配,因此要進行“繼續”編輯,只需有一個模板,該模板與您希望匹配的class_id屬性匹配,但在xpath表達式中的相關項上包括一個匹配項 。
例如,要改變PIMPL元素的類標識碼 ,添加該模板
<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屬性匹配,因此將替換其當前已匹配的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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.