如何使用XSL提取proct内指定节点并包裹至info元素
XML转换解决方案:提取并重组指定元素
需求回顾
完成以下XML转换:
- 从
<proct>元素中提取<list>、<note>、<caution>元素,移至<proct>外部 - 将上述提取的元素,与
<proct>外部的<graphelem>等元素一起包裹在<info>元素内 - 保留
<proct>元素内除上述三个元素外的其余内容
输入XML示例
<root> <graphelem>外部图形元素</graphelem> <otherinfo>外部辅助信息</otherinfo> <proct> <title>设备操作流程</title> <list> <item>检查设备供电</item> <item>启动控制开关</item> </list> <para>操作前请确认周围无障碍物</para> <note>每日操作后需清洁设备表面</note> <caution>禁止在设备运行时打开防护盖</caution> <step>按下启动按钮,等待设备初始化</step> </proct> </root>
预期输出XML
<root> <info> <graphelem>外部图形元素</graphelem> <otherinfo>外部辅助信息</otherinfo> <list> <item>检查设备供电</item> <item>启动控制开关</item> </list> <note>每日操作后需清洁设备表面</note> <caution>禁止在设备运行时打开防护盖</caution> </info> <proct> <title>设备操作流程</title> <para>操作前请确认周围无障碍物</para> <step>按下启动按钮,等待设备初始化</step> </proct> </root>
完善后的XSL样式表
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配根节点,构建输出结构 --> <xsl:template match="/root"> <root> <!-- 生成info元素,整合两类目标内容 --> <info> <!-- 复制proct之外的所有子元素 --> <xsl:copy-of select="*[not(self::proct)]"/> <!-- 复制proct内部的list、note、caution元素 --> <xsl:copy-of select="proct/list | proct/note | proct/caution"/> </info> <!-- 生成处理后的proct元素,保留非目标子元素 --> <proct> <xsl:copy-of select="proct/*[not(self::list or self::note or self::caution)]"/> </proct> </root> </xsl:template> <!-- 默认模板:保留文本节点与属性 --> <xsl:template match="text()|@*"> <xsl:copy/> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 根节点处理:直接构造输出的
<root>结构,优先生成<info>元素 - info元素内容:
- 用
*[not(self::proct)]筛选并复制所有<proct>之外的元素 - 用
proct/list | proct/note | proct/caution提取并复制<proct>内部的三个目标元素
- 用
- 处理后的proct元素:用
*[not(self::list or self::note or self::caution)]筛选并保留<proct>内除目标元素外的所有内容 - 默认模板:确保原XML中的文本节点和元素属性不会丢失
扩展适配
如果需要提取<proct>内所有后代层级的<list>、<note>、<caution>(而非仅直接子元素),可将选择器修改为:
<xsl:copy-of select="proct//list | proct//note | proct//caution"/>
如果存在多个<proct>元素,当前代码会自动提取所有<proct>内的目标元素并整合到<info>中,无需额外修改。
内容的提问来源于stack exchange,提问作者ak2103
相关产品推荐
相关产品推荐

