如何在xslt中将元素插入先前创建的元素中?

时间:2012-08-31 08:58:10

标签: xslt

我有一些来自数据库的记录,用于存档文件中的相应记录。

实施例 记录号XML

  1. <XML_FILE_HEADER file_name="sample.txt" />
  2. <XML_RECORD record_number="1" name="John Doe" Age="21"/>
  3. <XML_RECORD record_number="2" name""Jessica Sanchez" Age="23"/>
  4. <XML_FILE_FOOTER total_records="2"/>
  5. 现在,对于每条记录,我都有一个xslt模板,它将在xml中创建输出文件。

    对于记录号1:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
    <xsl:output method="xml"/>
    <xsl:template match="XML_FILE_HEADER">
        <xsl:element name="File">
        <xsl:attribute name="FileName"><xsl:value-of select="@file_name"/></xsl:attribute>
        </xsl:element>
      </xsl:element>
    </xsl:template>
    </xsl:stylesheet>
    

    对于记录2和3:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
         <xsl:output omit-xml-declaration="yes"/>
         <xsl:template match="XML_RECORD">
           <xsl:element name="Record">
            <xsl:attribute name="Name"><xsl:value-of select="@name"/></xsl:attribute>
            <xsl:element name="Details">
            <xsl:attribute name="Age"><xsl:value-of select="@Age"/></xsl:attribute>
            </xsl:element>
          </xsl:element>
         </xsl:template>
    </xsl:stylesheet>
    

    记录4:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
         <xsl:output omit-xml-declaration="yes"/>
         <xsl:template match="XML_FILE_FOOTER">
           <xsl:element name="Totals">
            <xsl:attribute name="Total Records"><xsl:value-of select="@total_records"/></xsl:attribute>
          </xsl:element>
         </xsl:template>
    </xsl:stylesheet>
    

    问题是,在使用上面的模板追加每条记录后,我会得到一个输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <File FileName="sample.txt"></File>
    <Record Name="John Doe" Age="21"></Record>
    <Record Name="Jessica Sanchez" Age="22"></Record>
    <Totals Total Records="2"></Totals>
    

    我如何能够在File下插入Record和Totals元素?所以它会有这样的输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <File FileName="sample.txt">
    <Record Name="John Doe" Age="21"></Record>
    <Record Name="Jessica Sanchez" Age="22"></Record>
    <Totals Total Records="2"></Totals>
    </File>
    

    非常感谢任何帮助。感谢。

2 个答案:

答案 0 :(得分:2)

简直如此

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="XML_FILE_HEADER"/>
 </xsl:template>

 <xsl:template match="XML_FILE_HEADER">
   <File FileName="{@file_name}">
     <xsl:apply-templates select="../*[not(self::XML_FILE_HEADER)]"/>
   </File>
 </xsl:template>

 <xsl:template match="XML_RECORD">
   <Record name="{@name}" Age="{@Age}"/>
 </xsl:template>

 <xsl:template match="XML_FILE_FOOTER">
   <Totals TotalRecords="{@total_records}"/>
 </xsl:template>
</xsl:stylesheet>

对提供的XML(已更正为格式良好的)文档应用此转换时:

<t>
    <XML_FILE_HEADER file_name="sample.txt" />
    <XML_RECORD record_number="1" name="John Doe" Age="21"/>
    <XML_RECORD record_number="2" name="Jessica Sanchez" Age="23"/>
    <XML_FILE_FOOTER total_records="2"/>
</t>

产生了想要的正确结果

<File FileName="sample.txt">
   <Record name="John Doe" Age="21"/>
   <Record name="Jessica Sanchez" Age="23"/>
   <Totals TotalRecords="2"/>
</File>

<强>解释

  1. 正确使用模板。

  2. 正确使用xsl:apply-templates订购结果。

  3. 正确使用AVT(属性值模板)。

  4. 避免使用xsl:element

  5. 使用xsl:call-template

  6. 实施&#34;推送风格&#34;几乎完全。

答案 1 :(得分:0)

你想要的是<xsl:call-template name="templatename" />元素。这允许您从另一个模板内部调用模板。

这样的东西
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
    <xsl:output method="xml"/>
    <xsl:template match="/XML_FILE/XML_FILE_HEADER">
      <xsl:element name="File">
        <xsl:attribute name="FileName">
          <xsl:value-of select="@file_name"/>
        </xsl:attribute>
        <xsl:for-each select="/XML_FILE/XML_RECORD">
          <xsl:call-template name="RecordTemplate" />
        </xsl:for-each>        
        <xsl:call-template name="TotalTemplate" />
      </xsl:element>
    </xsl:template>

    <xsl:template name="RecordTemplate">
      <xsl:element name="Record">
        <xsl:attribute name="Name"><xsl:value-of select="@name"/></xsl:attribute>
        <xsl:attribute name="Age"><xsl:value-of select="@Age"/></xsl:attribute>
      </xsl:element>
    </xsl:template>

    <xsl:template match="/XML_FILE/XML_FILE_FOOTER" name="TotalTemplate">
      <xsl:element name="Totals">
          <xsl:attribute name="Total Records"><xsl:value-of select="@total_records"/>
      </xsl:element>
    </xsl:template>
</xsl:stylesheet>

当然你的输入必须是XML有效的(即有一个根节点),如此

<XML_FILE>
  <XML_FILE_HEADER file_name="sample.txt" />
  <XML_RECORD record_number="1" name="John Doe" Age="21"/>
  <XML_RECORD record_number="2" name""Jessica Sanchez" Age="23"/>
  <XML_FILE_FOOTER total_records="2"/>
</XML_FILE>