能否通过XInclude仅引入XML元素的指定部分内容?
针对XInclude按需选择特定
标签的可行方案
结合你的需求(基于Saxon解析器,避免复杂XPath,实现根据引入文件选择目标XML中support下的单个
),以下是几个可行方案:
方案1:XInclude + XSLT后处理(推荐,兼顾灵活性与复用性)
XInclude本身不支持分支逻辑,可先通过XInclude引入完整内容,再用XSLT根据引入时指定的标识筛选目标
。
步骤:
- 修改目标XML:给每个需要选择的
添加唯一
xml:id标识:
<support> <material>wood</material> <material>paint</material> <p xml:id="support-note-1">第一段描述内容</p> <p xml:id="support-note-2">第二段描述内容</p> </support>
- 在引入文件中添加自定义选择标识:给
xi:include元素加自定义属性,指定要选择的的
xml:id:
<xi:include href="../Witness_Descriptions/Clopton_Chantry_Chapel.xml" xpointer="Clopton_Chantry_Chapel" xmlns:xi="http://www.w3.org/2001/XInclude" custom:selected-p="support-note-1"/>
(需自定义命名空间,比如xmlns:custom="http://your-project.com/ns")
- 编写XSLT处理逻辑:适配Saxon的XSLT 2.0/3.0,筛选并保留指定的
,同时保留其他内容:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="http://your-project.com/ns"> <!-- 匹配support节点,处理<p>的筛选 --> <xsl:template match="support"> <xsl:copy> <!-- 保留material等非<p>子节点 --> <xsl:apply-templates select="*[not(self::p)]"/> <!-- 获取引入时指定的<p>标识 --> <xsl:variable name="target-id" select="//xi:include/@custom:selected-p"/> <!-- 仅保留匹配的<p> --> <xsl:apply-templates select="p[@xml:id = $target-id]"/> </xsl:copy> </xsl:template> <!-- 默认复制所有其他节点与属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
方案2:拆分目标XML为基础片段+独立
文件(无需XSLT)
将目标XML的内容拆分为固定基础部分和多个独立的
片段,按需组合引入。
步骤:
拆分文件:
Clopton_Chantry_Chapel_base.xml:包含固定的基础结构(不含):
<sourceDesc xml:id="Clopton_base"> <msDesc xml:id="Clopton"> <!-- 其他固定内容 --> <physDesc> <objectDesc> <supportDesc> <support> <material>wood</material> <material>paint</material> </support> </supportDesc> </objectDesc> </physDesc> <!-- 其他固定内容 --> </msDesc> </sourceDesc>Clopton_p1.xml:仅包含第一个:
<p>第一段描述内容</p>Clopton_p2.xml:仅包含第二个:
<p>第二段描述内容</p>
按需组合引入:在不同的引入文件中,先引入基础片段,再引入对应的
文件:
<sourceDesc> <xi:include href="../Witness_Descriptions/Clopton_Chantry_Chapel_base.xml" xpointer="Clopton_base" xmlns:xi="http://www.w3.org/2001/XInclude"/> <!-- 根据需要选择引入Clopton_p1或Clopton_p2 --> <xi:include href="../Witness_Descriptions/Clopton_p1.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> </sourceDesc>
方案3:XPointer位置路径筛选(适合结构固定的场景)
如果Saxon支持XPointer的xpointer()语法,可以直接通过位置路径指定要选择的
,无需额外修改目标XML或使用XSLT。
示例(选择第一个
):
<xi:include href="../Witness_Descriptions/Clopton_Chantry_Chapel.xml" xpointer="xpointer(//sourceDesc[@xml:id='Clopton_Chantry_Chapel']//support/(material | p[1]))" xmlns:xi="http://www.w3.org/2001/XInclude"/>
要选择第二个
,只需将p[1]改为p[2]。注意:此方案依赖目标XML的结构稳定,如果后续新增/删除material或其他节点,位置索引会失效。
内容的提问来源于stack exchange,提问作者medievalmatt
相关产品推荐
相关产品推荐

