使用xslt生成xml,给定带有数据的xml和带有默认值的xml模板

时间:2014-05-21 13:32:33

标签: xml xslt

您好我遇到了xslt的麻烦,我会非常乐意为您提供帮助,

我有一个xml包含一些我想用xslt解析的数据和一个带有数据结构和空节点默认值的模板文件。

我想使用模板结构生成一个xml,使用默认值或输入xml给出的数据,具体取决于它是否有文本或为空。

我已尝试迭代节点,但我是xsl的新手,并且我没有得到任何清晰的信息,提前感谢。

数据:

<doc>
   <object>
      <group1> 
          <a>(<p>text here</p> or blank)</a>
          <b>(<p>text here</p> or blank)</b>
          <c>
             <c1>(<p>text here</p> or blank)</c1>
             <c2>(<p>text here</p> or blank)</c2>
          </c>
      </group1>
      <group2>
          <d>(<p>text here</p> or blank)</d>
      </group2>
   </object>
</doc>

模板:

<doc>
   <object>
      <group1> 
          <a><p>default text</p></a>
          <b><p>default text</p></b>
          <c>
             <c1><p>default text</p></c1>
             <c2><p>default text</p></c2>
          </c>
      </group1>
      <group2>
          <d><p>default text</p></d>
      </group2>
   </object>
</doc>

现在我正在生成输出xml,评估每个节点,如下所示:

<xsl:variable name="file" select="document('template.xml')"/>    
<a>
    <xsl:choose>
        <xsl:when test="//a != ''">
              <xsl:copy-of select="//a/p" />
        </xsl:when>
        <xsl:otherwise>
              <xsl:copy-of select="$file//a/p" />
        </xsl:otherwise>
    </xsl:choose> 
</a>
<b> ... </b> ...

迭代我正在尝试的代码导致所有空白:

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*[not(*) and not(text())]">
    <xsl:copy>
        <xsl:apply-templates select="$file//*[name()=name(current())]/p"/>
    </xsl:copy>
</xsl:template>

2 个答案:

答案 0 :(得分:0)

你用什么来解析你的xml文件?撒克逊?

您可以测试替换

<xsl:copy-of select="..." />

通过

<xsl:value-of select="..." />

但我认为问题不在这里。您必须以递归方式遍历所有节点,并且在空白的情况下,您应该解析此节点上的“Template.xml”值。

测试类似:

<xsl:template match="*">
   <xsl:choose>
    <xsl:when test="not(Current()='')">
          <xsl:value-of select="." />
    </xsl:when>
    <xsl:otherwise>
          <xsl:copy-of select="$file/name(Current())" />
    </xsl:otherwise>
</xsl:choose> 
</xsl:template>

我觉得它不起作用,因为我现在无法测试而忘记了语法,但它应该是这样的。

答案 1 :(得分:0)

我终于解决了,我在这里发布我的解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/*">
        <doc xml:lang="es">
            <xsl:apply-templates select="*"/>
        </doc>
    </xsl:template> 

    <xsl:template match="*">
        <xsl:copy>
            <xsl:choose>
              <xsl:when test="current() != ''">
                <xsl:choose>
                    <xsl:when test="self::p">
                        <xsl:copy-of select="node()"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="*"/>
                    </xsl:otherwise>
                </xsl:choose>
              </xsl:when>
              <xsl:otherwise>
                <xsl:variable name="file" select="document('template.xml')"/>
                <xsl:copy-of select ="$file//*[name()=name(current())]/p"/>
              </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>