XML特定字符串节点间内容提取:XSLT3.0实现咨询
精准提取XML中特定标记节点之间的内容(XSLT 3.0)
你的问题核心在于当前代码用了全局的following::ul[1],会匹配整个文档里第一个<ul>,而不是目标标记节点和下一个关键标记节点之间的<ul>,导致所有区块都重复了同一个列表。另外你需要明确界定几个关键内容的范围:Test Objective到Acceptance Criterion之间的内容、Acceptance Criterion到Prerequisite之间的内容(包含Test Note),以及Prerequisite自身的内容。
修正后的XSLT方案
我们可以先定位所有关键标记节点,再利用XSLT的节点顺序比较(<</>>)来精准选取节点范围,避免全局匹配的问题:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <testcases> <testcase> <xsl:attribute name="internalid"/> <xsl:attribute name="name"> <xsl:value-of select="/singlenode/title"/> </xsl:attribute> <node_order/> <externalid/> <version/> <summary> <xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text> <!-- 提取Test Objective及其到Acceptance Criterion之间的内容 --> <xsl:variable name="test-obj" select="/singlenode/p[b[contains(text(),'Test Objective') or contains(text(),'Test Objectives')]]"/> <xsl:variable name="accept-crit" select="/singlenode/p[b[contains(text(),'Acceptance Criterion') or contains(text(),'Acceptance Criteria')]]"/> <xsl:copy-of select="$test-obj"/> <xsl:copy-of select="$test-obj/following-sibling::node()[. << $accept-crit and not(self::p[b[contains(., 'Acceptance Criterion')]])]"/> <!-- 提取Acceptance Criterion及其到Prerequisite之间的内容(包含Test Note) --> <xsl:variable name="prereq" select="/singlenode/p[b[contains(text(),'Prerequisite') or contains(text(),'Prerequisites')]]"/> <xsl:copy-of select="$accept-crit"/> <xsl:copy-of select="$accept-crit/following-sibling::node()[. << $prereq and not(self::p[b[contains(., 'Prerequisite')]])]"/> <xsl:text disable-output-escaping="yes">]]></xsl:text> </summary> <preconditions> <xsl:text disable-output-escaping="yes"><![CDATA[<p></xsl:text> <!-- 提取Prerequisite及其后续相关内容 --> <xsl:copy-of select="$prereq"/> <xsl:copy-of select="$prereq/following-sibling::node()[not(self::p[b[contains(., 'Test Objective') or contains(., 'Acceptance Criterion')]])]"/> <xsl:text disable-output-escaping="yes"></p>]]></xsl:text> </preconditions> </testcase> </testcases> </xsl:template> </xsl:stylesheet>
关键改动说明
- 变量定位关键节点:先把
Test Objective、Acceptance Criterion、Prerequisite对应的<p>节点存为变量,避免重复查询,也让范围逻辑更清晰。 - 节点范围精准选择:用
following-sibling::node()[. << $target-node]选取当前节点之后、目标节点之前的所有兄弟节点,再用not()排除目标节点本身,确保只取中间的内容。 - 抛弃全局匹配:不再用
following::ul[1]这种全局查找,而是基于兄弟节点的顺序限定范围,每个区块只会拿到自己对应的后续列表或节点。
预期输出验证
用你的输入XML测试后,会得到符合要求的结果:
<summary>中包含Test Objective、Acceptance Criterion以及它们之间的内容,还有Test Note和对应的<ul><preconditions>中仅包含Prerequisite的内容,不会错误带入其他区块的列表
内容的提问来源于stack exchange,提问作者Avela
相关产品推荐
相关产品推荐

