显示没有父节点的子节点的XML

时间:2011-07-14 08:08:09

标签: css xml xslt xpath

我从我编写的程序中获得了以下XML调试转储。我希望将此格式化为一个表格,并嵌套子例外(我还没有那么远)。 我是XSL(T)的新手所以请耐心等待。 我有三个文件debug.xml,debug.xsl和table.css。显示不足

XML的文件

    <?xml version="1.0" encoding="ISO8859-1" ?>
<?xml-stylesheet type="text/xsl" href="debug.xsl"?>
<Root>
<Exception>
    <Type>DuplicateKeyPairException1</Type>
    <Message>Duplicate in the key/section pair found in the file. - [THRUSTERS/NRTHRUSTERS] already has a value.</Message>
    <Source>WindowsFormsApplication1</Source>
    <StackTrace>   at IniParser..ctor(String iniPath) in C:\Programming\CSharp\VisualSourceSafeInterface\Test2\WindowsFormsApplication1\WindowsFormsApplication1\IniParser.cs:line 110
   at CIniFile.Open(String sFileName) in C:\Programming\CSharp\VisualSourceSafeInterface\Test2\WindowsFormsApplication1\WindowsFormsApplication1\FileParser.cs:line 115
   at CIniFile..ctor(String sFilename) in C:\Programming\CSharp\VisualSourceSafeInterface\Test2\WindowsFormsApplication1\WindowsFormsApplication1\FileParser.cs:line 109
   at ScriptHost.RequestDocument(String qualifiedPath, enumFileType filetype) in C:\Programming\CSharp\VisualSourceSafeInterface\Test2\WindowsFormsApplication1\WindowsFormsApplication1\ScriptHost.cs:line 55</StackTrace>
    <TargetSite>Void .ctor(System.String)</TargetSite>
    <Data>
    <VSSFullPath>c:\vss\ERROR\vss\SRCSAFE.INI</VSSFullPath>
    <VSSFilename>xxx.ini</VSSFilename>
    </Data>
<Exception>
    <Type>System.ArgumentException</Type>
    <Message>Item has already been added. Key in dictionary: 'IniParser+SectionPair'  Key being added: 'IniParser+SectionPair'</Message>
    <Source>mscorlib</Source>
    <StackTrace>   at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
   at System.Collections.Hashtable.Add(Object key, Object value)
   at IniParser..ctor(String iniPath) in C:\Programming\CSharp\VisualSourceSafeInterface\Test2\WindowsFormsApplication1\WindowsFormsApplication1\IniParser.cs:line 95</StackTrace>
    <TargetSite>Void Insert(System.Object, System.Object, Boolean)</TargetSite>
</Exception>
</Exception>
<Exception>
    <Type>DuplicateKeyPairException2</Type>
    <Message>Duplicate in the key/section pair found in the file. - [THRUSTERS/NRTHRUSTERS] already has a value.</Message>
    <Source>WindowsFormsApplication1</Source>
    <StackTrace>   at IniParser..ctor(String iniPath) in C:\Programming\CSharp\VisualSourceSafeInterface\Test2\WindowsFormsApplication1\WindowsFormsApplication1\IniParser.cs:line 110
   at CIniFile.Open(String sFileName) in C:\Programming\CSharp\VisualSourceSafeInterface\Test2\WindowsFormsApplication1\WindowsFormsApplication1\FileParser.cs:line 115
   at CIniFile..ctor(String sFilename) in C:\Programming\CSharp\VisualSourceSafeInterface\Test2\WindowsFormsApplication1\WindowsFormsApplication1\FileParser.cs:line 109
   at ScriptHost.RequestDocument(String qualifiedPath, enumFileType filetype) in C:\Programming\CSharp\VisualSourceSafeInterface\Test2\WindowsFormsApplication1\WindowsFormsApplication1\ScriptHost.cs:line 55</StackTrace>
    <TargetSite>Void .ctor(System.String)</TargetSite>
    <Data>
    <VSSFullPath>c:\vss\ERROR\vss\SRCSAFE.INI</VSSFullPath>
    <VSSFilename>xxx.ini</VSSFilename>
    </Data>
</Exception>
</Root>

XSL文件

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >


    <xsl:template match="/">   
    <html>
    <head>
        <title>Cascading Style Sheet</title>
    <link rel="stylesheet" type="text/css" href="table.css" title="Style"/>
    </head>
    <body>
            <xsl:for-each select="Root">
                <xsl:element name="table">
                    <xsl:attribute name="border">1</xsl:attribute>
                        <xsl:for-each select="*">
                            <xsl:apply-templates select="."/>
                        </xsl:for-each>
                </xsl:element>
            </xsl:for-each>
    </body>
    </html> 
    </xsl:template>

    <xsl:template match="Root/Exception">
        <xsl:element name="tr">
            <xsl:element name="th">
            <xsl:attribute name="colspan">2</xsl:attribute>
            <xsl:attribute name="class">Exception</xsl:attribute>
            Exception
            </xsl:element>
        </xsl:element>
        <xsl:apply-templates select="Type"/>
        <xsl:apply-templates select="Message"/>
        <xsl:apply-templates select="VSSFullPath"/>
        <xsl:apply-templates select="VSSFilename"/>
        <xsl:apply-templates select="Source"/>
        <xsl:apply-templates select="TargetSite"/>
        <xsl:apply-templates select="StackTrace"/>
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="Exception/Exception">
        <xsl:element name="tr">
            <xsl:element name="th">
            <xsl:attribute name="colspan">2</xsl:attribute>
            <xsl:attribute name="class">Exception</xsl:attribute>
            SUB Exception
            </xsl:element>
        </xsl:element>
        <xsl:apply-templates select="Type"/>
        <xsl:apply-templates select="Message"/>
        <xsl:apply-templates select="Data"/>
        <xsl:apply-templates select="Source"/>
        <xsl:apply-templates select="TargetSite"/>
        <xsl:apply-templates select="StackTrace"/>
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="Type">
        <xsl:element name="tr">
            <xsl:element name="th">
                Type
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="Message">
        <xsl:element name="tr">
            <xsl:element name="th">
                Message
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="Source">
        <xsl:element name="tr">
            <xsl:element name="th">
                Source
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="TargetSite">
        <xsl:element name="tr">
            <xsl:element name="th">
                TargetSite
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="StackTrace">
        <xsl:element name="tr">
            <xsl:element name="th">
                StackTrace
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <!--Print data in a new table inside the cell-->
    <xsl:template match="Data">
        <xsl:element name="tr">
            <xsl:element name="th">
                Data
            </xsl:element>
            <xsl:element name="td">
                <xsl:element name="table">
                <xsl:attribute name="border">1</xsl:attribute>
                    <xsl:for-each select="*">
                        <xsl:element name="tr">
                            <xsl:element name="th">
                                <xsl:value-of select="local-name()"/>
                            </xsl:element>
                            <xsl:element name="td">
                                    <xsl:value-of select="."/>
                            </xsl:element>
                        </xsl:element>
                    </xsl:for-each>
                </xsl:element>
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="VSSFilename">
        <xsl:element name="tr">
            <xsl:element name="th">
                VSS File
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

                <!--Sub Exceptions
                <xsl:for-each select="child::Exception">
                    <xsl:element name="tr">
                        <xsl:element name="th">
                            Nested Exception
                        </xsl:element>
                        <xsl:element name="td">
                            <xsl:value-of select="." />
                        </xsl:element>
                    </xsl:element>
                </xsl:for-each>-->
 </xsl:stylesheet>

CSS-文件

table
{text-align: left;
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif ;
font-weight: normal;
font-size: 11px;
color: #fff;
width: 420px;
background-color: #666;
border: 0px;
border-collapse: collapse;
border-spacing: 0px;}

th {
    font: bold 11px "Trebuchet MS", Verdana, Arial, Helvetica,
    sans-serif;
    color: #6D929B;
    border-right: 1px solid #C1DAD7;
    border-bottom: 1px solid #C1DAD7;
    border-top: 1px solid #C1DAD7;
    letter-spacing: 2px;
    text-transform: uppercase;
    text-align: left;
    padding: 6px 6px 6px 12px;
    background: #CAE8EA url(images/bg_header.jpg) no-repeat;
}


th.Exception
{ 
    border-right: 1px solid #D7DAC1;
    border-bottom: 1px solid #D7DAC1;
    border-top: 1px solid #D7DAC1;
    border-top: 0;
    border-left: 0;
    border-right: 1px solid #D7DAC1;
    background: #EAE8CA;
}

td {
font-weight: bold;
    border-right: 1px solid #C1DAD7;
    border-bottom: 1px solid #C1DAD7;
    background: #fff;
    padding: 6px 6px 6px 12px;
    color: #6D929B;
}


td.alt {
    background: #F5FAFA;
    color: #B4AA9D;
}

我的结果显示了例外,但它也第二次显示了子节点的样式 所以我在列表中得到了一组双重例外子项。 PS这是正在进行的工作,如果你看到ordonary的任何东西,我真的很感激,如果你给我一个提示或指针什么是错误或不好的做法。 我确实理解为什么会这样,因为它运行所有模板而不是如何阻止它发生。

提前致谢,任何帮助。

3 个答案:

答案 0 :(得分:1)

  

我的结果显示了例外情况,但它也第二次显示了子节点的样式,因此我在列表中得到了一组双重例外。

不需要的重复项是由于XSLT xsl:apply-templates的错误使用造成的。

通常,在相同的序列构造函数中,您使用xsl:apply-templatesselect或不使用select,而不是

例如,这段代码:

    <xsl:apply-templates select="Type"/>
    <xsl:apply-templates select="Message"/>
    <xsl:apply-templates select="VSSFullPath"/>
    <xsl:apply-templates select="VSSFilename"/>
    <xsl:apply-templates select="Source"/>
    <xsl:apply-templates select="TargetSite"/>
    <xsl:apply-templates select="StackTrace"/>
    <xsl:apply-templates />

应改为:

    <xsl:apply-templates />

使用此说明,没有select,默认情况下会将模板应用于上下文节点的所有子项

要获得想要的结果,您只需在模板<xsl:apply-templates />Root/Exception模板中使用Exception/Exception。这是因为很明显你希望模板与所有孩子结盟。


PS:通过删除不需要的xsl:for-each,您的代码可以得到真正的改进。例如,这是你的(让我说惊人的)迭代:

   <xsl:for-each select="*">
    <xsl:apply-templates select="."/>
   </xsl:for-each>

在逻辑上等同于:

   <xsl:apply-templates />

答案 1 :(得分:1)

无法拒绝审核您的样式表。

此处 53行与原始 161 相比。

干杯。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:template match="/">   
        <html>
            <head>
                <title>Cascading Style Sheet</title>
                <link rel="stylesheet" type="text/css" href="table.css" title="Style"/>
            </head>
            <body>
                <table border="1">
                    <xsl:apply-templates />
                </table>
            </body>
        </html> 
    </xsl:template>

    <xsl:template match="Exception[parent::Root]">
        <tr>
            <th colspan="2" class="Exception">Exception</th>
        </tr>
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="Exception[parent::Exception]">
        <tr>
            <th colspan="2" class="Exception">SUB Exception</th>
        </tr>
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="Data">
        <tr>
            <th>Data</th>
            <td>
                <table border="1">
                        <xsl:apply-templates/>
                </table>
            </td>
        </tr>
    </xsl:template>

    <xsl:template match="Type|Message|Source|TargetSite|StackTrace|VSSFilename|VSSFullPath">
        <tr>
            <th>
                <xsl:value-of select="name()"/>
            </th>
            <td>
                <xsl:value-of select="."/>
            </td>
        </tr>
    </xsl:template>

</xsl:stylesheet>

答案 2 :(得分:0)

您的解决方案只需修改:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >


    <xsl:template match="/">
        <html>
            <head>
                <title>Cascading Style Sheet</title>
                <link rel="stylesheet" type="text/css" href="table.css" title="Style"/>
            </head>
            <body>
                <table border="1">
                    <xsl:apply-templates select="Root/Exception"/>
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="Root/Exception">
        <tr>
            <th colspan="2" class="Exception">Exception</th>
        </tr>
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="Exception/Exception">
        <xsl:element name="tr">
            <xsl:element name="th">
                <xsl:attribute name="colspan">2</xsl:attribute>
                <xsl:attribute name="class">Exception</xsl:attribute>
                SUB Exception
            </xsl:element>
        </xsl:element>
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="Type">
        <xsl:element name="tr">
            <xsl:element name="th">
                Type
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="Message">
        <xsl:element name="tr">
            <xsl:element name="th">
                Message
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="Source">
        <xsl:element name="tr">
            <xsl:element name="th">
                Source
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="TargetSite">
        <xsl:element name="tr">
            <xsl:element name="th">
                TargetSite
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="StackTrace">
        <xsl:element name="tr">
            <xsl:element name="th">
                StackTrace
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <!--Print data in a new table inside the cell-->
    <xsl:template match="Data">
        <xsl:element name="tr">
            <xsl:element name="th">
                Data
            </xsl:element>
            <xsl:element name="td">
                <xsl:element name="table">
                    <xsl:attribute name="border">1</xsl:attribute>
                    <xsl:for-each select="*">
                        <xsl:element name="tr">
                            <xsl:element name="th">
                                <xsl:value-of select="local-name()"/>
                            </xsl:element>
                            <xsl:element name="td">
                                <xsl:value-of select="."/>
                            </xsl:element>
                        </xsl:element>
                    </xsl:for-each>
                </xsl:element>
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <xsl:template match="VSSFilename">
        <xsl:element name="tr">
            <xsl:element name="th">
                VSS File
            </xsl:element>
            <xsl:element name="td">
                <xsl:value-of select="." />
            </xsl:element>
        </xsl:element>
    </xsl:template>

    <!--Sub Exceptions
                <xsl:for-each select="child::Exception">
                    <xsl:element name="tr">
                        <xsl:element name="th">
                            Nested Exception
                        </xsl:element>
                        <xsl:element name="td">
                            <xsl:value-of select="." />
                        </xsl:element>
                    </xsl:element>
                </xsl:for-each>-->
</xsl:stylesheet>

你也可以简单地写

<table border="1">

大于

<xsl:element name="table">
    <xsl:attribute name="border">1</xsl:attribute>

提高可读性。

相关问题