xml - 使用 XSLT 自动创建 xml 元素

标签 xml xslt xpath

我想根据输入文件表达式自动化元素。

我的输入文件看起来像

<?xml version="1.0" encoding="UTF-8"?>
<mappings>
    <mapping inputContext="InputRoot" outputContext="outputRoot">
        <input>InputParent/InputChild/InputSubChild</input>
        <output>OutputParent/OPChild</output>
    </mapping>
</mappings>

基于上面的 XML,我创建了下面的 XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns="http://www.testmapping.org/mapping">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <xsl:variable name="outputCtxt" select="mappings/mapping/output"/>
        <xsl:call-template name="contextGenerator">
            <xsl:with-param name="contextPath" select="$outputCtxt"/>
        </xsl:call-template>
    </xsl:template>
    <xsl:template name="contextGenerator">
        <xsl:param name="contextPath" as="xs:string?"/>
        <xsl:variable name="currentContext" select="substring-before($contextPath,'/')"/>
        <xsl:variable name="subContext" select="substring-after($contextPath,'/')"/>
        <xsl:element name="{$currentContext}">
            <xsl:call-template name="contextGenerator">
                <xsl:with-param name="contextPath" select="$subContext"/>
            </xsl:call-template>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

我期待以下格式的输出

<outputRoot>
   <OutputParent>
      <OPChild></OPChild>
   </OutputParent>
</outputRoot>

当我尝试根据输入进行转换时,我以预期的 QName 错误结束。我能有解决这个问题的建议吗?

最佳答案

contextGenerator 模板未正确拆分和递归。 (第二次调用时 contextGenerator 的参数中没有 /,因此拆分失败。)

将以下内容添加到模板有助于显示问题:

<xsl:message>
    [<xsl:value-of select="$currentContext"/>] 
    [<xsl:value-of select="$subContext"/>]
</xsl:message>

输出:

[OutputParent] 
[OPChild]
[] 
[]

以下替换模板会产生正确的输出:

<xsl:template name="contextGenerator">
    <xsl:param name="contextPath" as="xs:string?"/>
    <xsl:choose>
        <xsl:when test="contains($contextPath, '/')">
            <xsl:element name="{substring-before($contextPath, '/')}">
                <xsl:variable name="subContext" 
                              select="substring-after($contextPath, '/')"/>
                <xsl:if test="$subContext">
                    <xsl:call-template name="contextGenerator">
                        <xsl:with-param name="contextPath" select="$subContext"/>
                    </xsl:call-template>
                </xsl:if>
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="{$contextPath}"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

结果:

<OutputParent>
   <OPChild/>
</OutputParent>

关于xml - 使用 XSLT 自动创建 xml 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8450381/

相关文章:

xslt - XPath:无法从选定的标签中获取正确的值

xpath - 为什么这个//ID 通过但//DEF 失败?

xml - EXSL-如何使用str:tokenize()?

java - 如何在不知道对象结构的情况下通过XStream库将XML转换为Java对象

java - XML 属性值中无法识别换行符? Java、DOM、JTextArea

java - 如何为自定义 baseadapter 类中的项目设置自定义 ListView 字体

python - 元素不可见异常 : element not visible Python

java - hyperjaxb3 : Enumeration questions

xml - 使用 XPATH 函数时出现问题

excel - XSLT 输出 BOM 字符在 Excel 中可见