如何在XSLT模板指定位置正确插入XML元数据字符串
XSLT插入指定XML片段的实现方案
报错原因
你触发的'xsl:template' cannot be a child of the 'mdmec:Basic' element报错,核心原因是违反XSLT基础语法规则:xsl:template属于顶级元素,仅能作为xsl:stylesheet/xsl:transform根节点的直接子节点存在,不允许嵌套在其他模板、输出XML节点内部。
实现方式
根据你要插入的People元数据是静态固定内容、还是需要从源XML动态读取,分两种场景处理:
场景1:插入静态固定的People元数据
如果md命名空间下的People片段是固定写死的内容,不需要从源XML读取,直接按以下步骤操作:
- 先在XSLT的根节点
xsl:stylesheet上补充声明md对应的命名空间URI(替换成你实际业务中使用的md命名空间地址),避免输出时自动生成无意义的ns前缀。<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:md="http://replace-with-your-md-namespace-uri" xmlns:mdmec="http://replace-with-your-mdmec-namespace-uri"> - 找到
<!-- INSERT "People" Metadata XML STRING HERE -->标记位置(也就是</md:LocalizedInfo>闭合标签之后、mdmec:Basic节点内部),直接把你的People XML片段原封不动放在这里即可,不需要套任何xsl:template标签。
示例写法:<mdmec:Basic> <!-- 原有逻辑保留 --> <md:LocalizedInfo> <!-- 原有LocalizedInfo内部节点逻辑 --> </md:LocalizedInfo> <!-- 直接插入静态People片段即可 --> <md:People> <md:Job>导演</md:Job> <md:Name>张三</md:Name> <!-- 按你的实际结构补充其他演职人员子节点 --> </md:People> </mdmec:Basic>
场景2:动态读取源XML中的People元数据
如果People节点内容需要从输入的源XML中读取、甚至要做结构调整/字段过滤,不要嵌套写模板,按以下方式处理:
- 不需要修改People结构的场景:直接在插入位置用
xsl:copy-of拷贝对应节点即可,把XPath替换成你源XML中People节点的实际路径:</md:LocalizedInfo> <!-- 拷贝源XML中对应路径的People节点 --> <xsl:copy-of select="/Root/md:People" /> - 需要自定义转换People逻辑的场景:把People的处理模板定义为顶级元素(和
match="/"的根模板同级,都放在xsl:stylesheet节点下),然后在插入位置用xsl:apply-templates调用即可。
示例代码结构:<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:md="http://replace-with-your-md-namespace-uri" xmlns:mdmec="http://replace-with-your-mdmec-namespace-uri"> <!-- 原有根模板,不要在内部嵌套xsl:template --> <xsl:template match="/"> <mdmec:Basic> <md:LocalizedInfo> <!-- 原有LocalizedInfo逻辑 --> </md:LocalizedInfo> <!-- 插入位置调用People节点的处理模板 --> <xsl:apply-templates select="/Root/md:People" /> </mdmec:Basic> </xsl:template> <!-- People处理模板,和根模板平级,作为stylesheet的直接子节点 --> <xsl:template match="md:People"> <md:People> <!-- 这里写自定义转换逻辑,比如过滤只保留导演条目 --> <xsl:for-each select="md:Person[md:Job='导演']"> <xsl:copy-of select="." /> </xsl:for-each> </md:People> </xsl:template> </xsl:stylesheet>
注意事项
- 所有用到的命名空间前缀(md、mdmec)必须在
xsl:stylesheet根节点统一声明,不要在内部输出节点上临时声明,避免输出XML出现命名空间前缀混乱的问题。 - 任何
xsl:template元素都不能嵌套在其他元素内部,否则必然触发语法报错。
内容的提问来源于stack exchange,提问作者rency0722
相关产品推荐
相关产品推荐

