子节点使用XSLT循环两次

时间:2015-04-01 09:11:45

标签: xml html5 xslt

我有一个输入XML,如下所示:

<xml>

<Form Name ="VB.Form" Id ="Form1" BackColor="&amp;H0080FF80&amp;" Caption="Form1" ClientHeight="7395" ClientLeft="120" ClientTop="450" ClientWidth="13815" LinkTopic="Form1" ScaleHeight="7395" ScaleWidth="13815" StartUpPosition="3  'Windows Default">
<PictureBox Name ="VB.PictureBox" Id ="Picture2" Height="975" Left="4320" ScaleHeight="915" ScaleWidth="3675" TabIndex="14" Top="5880" Width="3735"></PictureBox>
<Frame Name ="VB.Frame" Id ="Frame1" BackColor="&amp;H00C0C0C0&amp;" Caption="Frame1" Height="4095" Left="840" TabIndex="2" Top="1560" Width="11535">
<CommandButton Name ="VB.CommandButton" Id ="Command2" Caption="Command2" Height="375" Left="720" TabIndex="11" Top="3480" Width="1095"></CommandButton>
<Frame Name ="VB.Frame" Id ="Frame2" BackColor="&amp;H00E0E0E0&amp;" Caption="Frame2" Height="3855" Left="6720" TabIndex="7" Top="120" Width="4695">
<Label Name ="VB.Label" Id ="Label1" Caption="This is a Test of a label" Height="735" Left="960" TabIndex="8" Top="840" Width="1935"></Label></Frame>
<PictureBox Name ="VB.PictureBox" Id ="Picture1" BackColor="&amp;H00E0E0E0&amp;" Height="2175" Left="3600" ScaleHeight="2115" ScaleWidth="2835" TabIndex="6" Top="1560" Width="2895"></PictureBox>
<ComboBox Name ="VB.ComboBox" Id ="Combo1" Height="315" Left="3600" TabIndex="5" Text="Combo1" Top="1080" Width="2655"></ComboBox>
<ListBox Name ="VB.ListBox" Id ="List1" Height="1425" Left="600" TabIndex="4" Top="1200" Width="2295"></ListBox>
<TextBox Name ="VB.TextBox" Id ="Text2" Height="615" Left="600" TabIndex="3" Text="Text2" Top="480" Width="2415"></TextBox>
<Label Name ="VB.Label" Id ="Label3" Caption="Label3" Height="255" Left="5760" TabIndex="10" Top="240" Width="615"></Label>
<Shape Name ="VB.Shape" Id ="Shape1" Height="615" Left="4200" Top="240" Width="1095"></Shape>
<Image Name ="VB.Image" Id ="Image1" Height="3135" Left="7200" Top="480" Width="3855"></Image></Frame>
<TextBox Name ="VB.TextBox" Id ="Text1" Height="375" Left="360" TabIndex="1" Text="Text1" Top="840" Width="2535"></TextBox>
</Form>

</xml>

但是我的情况如下所示:使用my xslt生成两次子元素和框架下的cild元素的框架:

<!DOCTYPE HTML SYSTEM "about:legacy-compat"><html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="UTF-8">
        <title>Form1</title>
    </head>
    <body>
        <DIV><Canvas id="Picture2" Height="975" Width="3735" style="position: absolute;padding-left:4320px;padding-top:5880px;"></Canvas><Div id="Frame1" Height="4095" Width="11535" style="position: absolute;background:White;padding-left:840px;padding-top:1560px;"><div  id="Command2" Height="375" Width="1095" style="position: absolute;padding-left:720px;padding-top:3480px;"><input type="submit" style="width:100%; height:100%;" value="Submit" id="Command2"/></div><Div id="Frame2" Height="3855" Width="4695" style="position: absolute;background:White;padding-left:6720px;padding-top:120px;"><label id="Label1" Height="735" Width="1935" style="position: absolute;padding-left:960px;padding-top:840px;"></label></Div><div id="Frame2" Height="3855" Width="4695" style="position: absolute;background:White;padding-left:6720px;padding-top:120px;"><label id="Label1" Height="735" Width="1935" style="position: absolute;padding-left:960px;padding-top:840px;"></label></div><Canvas id="Picture1" Height="2175" Width="2895" style="position: absolute;background:Gray;padding-left:3600px;padding-top:1560px;"></Canvas><div  id="Combo1" Height="315" Width="2655" style="position: absolute;padding-left:3600px;padding-top:1080px;"><select multiple="multiple" id="Combo1"/></div><div  id="List1" Height="1425" Width="2295" style="position: absolute;padding-left:600px;padding-top:1200px;"><select multiple="multiple" id="List1"/></div><Div id="List1" Height="1425" Width="2295" style="position: absolute;padding-left:600px;padding-top:1200px;"></Div><div  id="Text2" Height="615" Width="2415" style="position: absolute;padding-left:600px;padding-top:480px;"><input type = "text" id = "myText" style="width:100%; height:100%;" value = "text here" id="Text2"/></div><label id="Label3" Height="255" Width="615" style="position: absolute;padding-left:5760px;padding-top:240px;"></label><Div id="Shape1" Height="615" Width="1095" style="position: absolute;padding-left:4200px;padding-top:240px;"></Div><img id="Image1" Height="3135" Width="3855" style="position: absolute;padding-left:7200px;padding-top:480px;"></img></Div><div id="Frame1" Height="4095" Width="11535" style="position: absolute;background:White;padding-left:840px;padding-top:1560px;"><div  id="Command2" Height="375" Width="1095" style="position: absolute;padding-left:720px;padding-top:3480px;"><input type="submit" style="width:100%; height:100%;" value="Submit" id="Command2"/></div><Div id="Frame2" Height="3855" Width="4695" style="position: absolute;background:White;padding-left:6720px;padding-top:120px;"><label id="Label1" Height="735" Width="1935" style="position: absolute;padding-left:960px;padding-top:840px;"></label></Div><div id="Frame2" Height="3855" Width="4695" style="position: absolute;background:White;padding-left:6720px;padding-top:120px;"><label id="Label1" Height="735" Width="1935" style="position: absolute;padding-left:960px;padding-top:840px;"></label></div><Canvas id="Picture1" Height="2175" Width="2895" style="position: absolute;background:Gray;padding-left:3600px;padding-top:1560px;"></Canvas><div  id="Combo1" Height="315" Width="2655" style="position: absolute;padding-left:3600px;padding-top:1080px;"><select multiple="multiple" id="Combo1"/></div><div  id="List1" Height="1425" Width="2295" style="position: absolute;padding-left:600px;padding-top:1200px;"><select multiple="multiple" id="List1"/></div><Div id="List1" Height="1425" Width="2295" style="position: absolute;padding-left:600px;padding-top:1200px;"></Div><div  id="Text2" Height="615" Width="2415" style="position: absolute;padding-left:600px;padding-top:480px;"><input type = "text" id = "myText" style="width:100%; height:100%;" value = "text here" id="Text2"/></div><label id="Label3" Height="255" Width="615" style="position: absolute;padding-left:5760px;padding-top:240px;"></label><Div id="Shape1" Height="615" Width="1095" style="position: absolute;padding-left:4200px;padding-top:240px;"></Div><img id="Image1" Height="3135" Width="3855" style="position: absolute;padding-left:7200px;padding-top:480px;"></img></div><div  id="Text1" Height="375" Width="2535" style="position: absolute;padding-left:360px;padding-top:840px;"><input type = "text" id = "myText" style="width:100%; height:100%;" value = "text here" id="Text1"/></div></DIV>
    </body>
</html>

        --------

我的xslt看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" />
    <xsl:variable name="vbLookup" select="document('Vblookup.xml')/VbLookup"/>
    <xsl:param name="list1" select="$vbLookup/*"/>
    <xsl:param name="list2" select="xml/Form/*"/>
    <xsl:param name="formName" select="xml/Form/@Name"/>

    <xsl:template match="/">
        <html>
            <head>
                <meta charset="UTF-8"/>
                <title><xsl:value-of select="xml/Form/@Caption"/></title>
            </head>
            <body>
                <xsl:call-template name="process-form"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template name="process-form" match="Form">
        <xsl:for-each select="$vbLookup/VBFormObject">
            <xsl:if test="@Name=$formName">
                <xsl:element name="{@Html5Object}">
                    <xsl:call-template name="process-children"/>
                </xsl:element>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="process-children">
        <xsl:for-each select="$list2">
                <xsl:call-template name="make-html-elements">
                        <xsl:with-param name="name" select="@Name"/>
                        <xsl:with-param name="id1" select="@Id"/>
                        <xsl:with-param name="childNodes" select="child::node()"/>
                </xsl:call-template> 
            </xsl:for-each>
    </xsl:template>



    <xsl:template name="make-html-elements">
        <xsl:param name="name" />
        <xsl:param name="id1"/>
        <xsl:param name="childNodes"/>
        <xsl:for-each select="$list1">
        <xsl:if test="@Name=$name and not(contains(@Html5Object,'input')) and not(contains(@Html5Object,'select'))">
                <xsl:text disable-output-escaping="yes"><![CDATA[<]]></xsl:text>
                <xsl:value-of select="@Html5Object"/> 
                <xsl:text> id="</xsl:text><xsl:value-of select="$id1"/>
                <xsl:text>"</xsl:text>
                <xsl:text disable-output-escaping="yes"><![CDATA[>]]></xsl:text>
                <xsl:for-each select="$childNodes">
                    <xsl:variable name="fname" select="@Name"/>
                    <xsl:variable name="id" select="@Id"/>
                    <xsl:variable name="fchildNode" select="child::node()"/>
                    <xsl:call-template name="make-html-elements">
                        <xsl:with-param name="name" select="$fname"/>
                        <xsl:with-param name="childNodes" select="$fchildNode"/>
                </xsl:call-template> 
                </xsl:for-each>
                <xsl:text disable-output-escaping="yes"><![CDATA[</]]></xsl:text>
                <xsl:value-of select="@Html5Object"/><xsl:text disable-output-escaping="yes"><![CDATA[>]]></xsl:text>
                </xsl:if>
            </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Vlookup XML看起来如下:

<VbLookup>
<VBFormObject Name = ' VB.CommandButton' Html5Object='Button' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'Gray'/>
<Top Html5='padding-top' Default = '0'/>
<Width Html5='Width' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>
  </VBFormObject>

<VBFormObject Name = 'VB.PictureBox' Html5Object='Canvas' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'Gray'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>

<VBFormObject Name = 'VB.ListBox' Html5Object='select multiple="multiple"' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>

<VBFormObject Name = 'VB.Frame' Html5Object='Div' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.CheckBox' Html5Object='Div' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.ComboBox' Html5Object='select multiple="multiple"' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.CommandButton' Html5Object='input type="submit" style="width:100%; height:100%;" value="Submit"'>
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.Data' Html5Object='Div' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.DirListBox' Html5Object='Div' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.DriveListBox' Html5Object='Div' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.FileListBox' Html5Object='Div'  >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.Form' Html5Object='DIV' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.Frame' Html5Object='div' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.HScrollBar' Html5Object='Div' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.Image' Html5Object='img' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>
          </VBFormObject>
<VBFormObject Name = 'VB.Label' Html5Object='label' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.Line' Html5Object='Div' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.ListBox' Html5Object='Div'  >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.Shape' Html5Object='Div' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>
<VBFormObject Name = 'VB.TextBox' Html5Object='input type = "text" id = "myText" style="width:100%; height:100%;" value = "text here"' >
    <Properties>
        <Height Html5='Height' Default = '0'/>
        <Left Html5 = 'padding-left' Default='0'/>
        <BackColor Html5 = 'background' Default = 'White'/>
            <Top Html5='padding-top' Default = '0'/><Width Html5='Width' Default = '0'/></Properties>

          </VBFormObject>

</VbLookup>

我不知道每次执行两次生成子节点两次是不正确的。 蚂蚁帮助将不胜感激。提前致谢

1 个答案:

答案 0 :(得分:0)

我不知道为什么你的代码没有做你想做的事情。正如我在评论中提到的,我无法重现您的结果。我怀疑你的代码太复杂了 - 让我建议一个更简单的替代方案:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

<xsl:param name="vbLookup" select="document('Vblookup.xml')"/>

<xsl:key name="map" match="VBFormObject" use="@Name" />

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

<xsl:template match="/">
    <html>
        <head>
            <meta charset="UTF-8"/>
            <title><xsl:value-of select="'PUT THE PATH TO YOUR TITLE HERE'"/></title>
        </head>
        <body>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

<!-- rename elements -->    
<xsl:template match="*" priority="1">
    <xsl:variable name="name">
        <xsl:variable name="source-name" select="local-name()" />
        <!-- switch context to use key -->
        <xsl:for-each select="$vbLookup">
            <xsl:variable name="target-name" select="key('map', $source-name)/@Html5Object" />
            <xsl:choose>
                <xsl:when test="$target-name">
                    <xsl:value-of select="$target-name"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$source-name"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:variable>
    <xsl:element name="{$name}">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

当这个应用于您的输入示例时(在将两个XML文件更正为格式良好之后!),结果为:

<!DOCTYPE html
  SYSTEM "about:legacy-compat">
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <meta charset="UTF-8">
      <title>PUT THE PATH TO YOUR TITLE HERE</title>
   </head>
   <body>
      <Div>
         <Div id="1"></Div>
         <C id="2">
            <D id="3"></D>
         </C>
      </Div>
   </body>
</html>

如果您可以确定输入XML中的每个可能元素在查找文档中都有一个条目,那么可以通过删除测试来进一步简化。