[英]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.