XML для дочерних узлов отображается без родителя - PullRequest
2 голосов
/ 14 июля 2011

У меня есть следующий отладочный дамп в 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 это работа в процессе, если вы видите что-то необычное, я действительно ценю это, если вы дадите мне подсказку или указатель на то, что неправильно или плохо. Я понимаю, почему это происходит, поскольку он запускает все шаблоны, но не знает, как это предотвратить.

Заранее спасибо за любую помощь.

Ответы [ 3 ]

1 голос
/ 14 июля 2011

Мой результат показывает исключения, но он также показывает стили для подузлов во второй раз, поэтому я получаю двойной набор дочерних исключений в списке.

Нежелательные дубликаты вызваны неправильным использованием xsl:apply-templates в вашем XSLT .

Обычно в том же конструкторе последовательности вы используете xsl:apply-templates с select или без 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 голос
/ 14 июля 2011

Не удержался при просмотре таблицы стилей.

Здесь 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>
0 голосов
/ 14 июля 2011

Ваше решение просто изменено:

<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>

для улучшения читабельности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...