如何打印XInclude引用层级,libxml2是否支持访问包含历史?
问题1:libxml2是否符合该规范要求,会存储XInclude包含历史?
libxml2完全符合W3C XInclude规范对包含历史存储的要求。你在执行XInclude解析时开启相关配置项后,所有实际被包含的顶层节点都会自动携带http://www.w3.org/2003/XInclude命名空间下的include-history扩展属性,属性值为按递归引用顺序排列的xi:include元素信息列表,完整记录引用链路。
问题2:通过哪些API调用(优先使用XSLT)可以访问该包含历史?
XSLT访问方式(基于libxslt处理器,和libxml2配套)
你只需要在XSLT文件中预先声明XInclude命名空间xmlns:xi="http://www.w3.org/2003/XInclude",就可以直接通过XPath表达式@xi:include-history获取节点的包含历史属性,属性中可以提取每一层引用的href、xpointer等参数。
示例XSLT框架如下:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2003/XInclude"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:text>sample1.xml
</xsl:text> <xsl:apply-templates select="*"/> </xsl:template> <xsl:template match="*"> <xsl:if test="@xi:include-history"> <!-- 按层级缩进输出对应引用的href值即可生成你需要的树结构 --> <xsl:value-of select="concat(substring(' ', 1, count(@xi:include-history/xi:include) * 4), '|- ', @xi:include-history/xi:include[last()]/@href, '
')"/> </xsl:if> <xsl:apply-templates select="*"/> </xsl:template> </xsl:stylesheet>
原生API访问方式
- C语言libxml2:使用
xmlNodeGetNsProp(node, BAD_CAST "include-history", BAD_CAST "http://www.w3.org/2003/XInclude")获取属性值 - Python lxml绑定:使用
element.attrib['{http://www.w3.org/2003/XInclude}include-history']获取属性值
额外说明:如果你的需求仅为生成引用层级树,也可以选择不执行完整的XInclude解析,直接递归扫描目标文件内的xi:include节点,结合xpointer表达式判断是否命中目标内容,过滤不需要的引用链路即可。
问题3:我对该规范的理解是否存在偏差?
你对规范的理解完全正确。XInclude的包含历史仅记录实际被解析并纳入结果树的节点的引用链路,你示例中sample2.xml的otherElem节点下引用的sampleX.xml,因为sample1.xml引用sample2.xml时的xpointer选择的是/root/elem/*,该部分内容不会被纳入sample1的结果树,因此不会出现在包含历史中,刚好符合你不需要统计sampleX.xml的需求。
内容的提问来源于stack exchange,提问作者oerkelchen
相关产品推荐
相关产品推荐

