XSL генерирует вложенный список - элементы повторяются - PullRequest
0 голосов
/ 24 октября 2018

Привет, у меня есть простая таблица стилей XSL, которая создает вложенный список из плоского XML-файла (файл должен быть плоским - это способ, которым программа выводит его).

Однако в конце спискаэто повторяет все пункты, и я не понимаю, почему.Я ограничен использованием XSL V1.0.

XML:

<QueryResults ReportName="Document Hierarchy Visio" ReportID="216">
    <Data RecordCount="186">
        <DataRow index="1">
            <parentid_visio></parentid_visio>
            <childid_visio>111</childid_visio>
            <parent_id>1</parent_id>
            <child_id>1</child_id>
            <formname>Patient</formname>
            <lvl>1</lvl>
            <patrank>1</patrank>
        </DataRow>
        <DataRow index="2">
            <parentid_visio>111</parentid_visio>
            <childid_visio>213</childid_visio>
            <parent_id>1</parent_id>
            <child_id>3</child_id>
            <formname>Alias</formname>
            <lvl>2</lvl>
            <patrank>1</patrank>
        </DataRow>
        <DataRow index="3">
            <parentid_visio>111</parentid_visio>
            <childid_visio>214</childid_visio>
            <parent_id>1</parent_id>
            <child_id>4</child_id>
            <formname>Address</formname>
            <lvl>2</lvl>
            <patrank>1</patrank>
        </DataRow>
    </Data>
</QueryResults>

XSL:

<?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" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:key name="child" match="DataRow" use="parentid_visio" />

<xsl:template match="Data">

    <div class="tree">
        <ul>
                <xsl:apply-templates select="DataRow[not(DataRow/parentid_visio)]"/>
        </ul>
    </div>
</xsl:template>

<xsl:template match="DataRow">
           <li>
            <a href="#"><xsl:value-of select="formname"/></a>

          <xsl:if test="key('child', childid_visio)">
               <ul>
                   <xsl:apply-templates select="key('child', childid_visio)[not(DataRow/parentid_visio)]"/>
               </ul>
            </xsl:if> 

           </li>
</xsl:template>

</xsl:stylesheet>

Это должно выдавать

<div class="tree">
   <ul>
      <li><a href="#">Patient</a>
<ul>
            <li><a href="#">Alias</a></li>
            <li><a href="#">Address</a></li>
            <li><a href="#">Alert</a></li>
            <li><a href="#">Contact</a></li>
            <li><a href="#">GP Detail</a></li>
            <li><a href="#">School Detail</a></li>
            <li><a href="#">Other Agency</a></li>
         </ul>
      </li>
     </ul>
</div>

но вместо этого возвращается:

<div class="tree">
   <ul>
      <li><a href="#">Patient</a><ul>
            <li><a href="#">Alias</a></li>
            <li><a href="#">Address</a></li>
            <li><a href="#">Alert</a></li>
            <li><a href="#">Contact</a></li>
            <li><a href="#">GP Detail</a></li>
            <li><a href="#">School Detail</a></li>
            <li><a href="#">Other Agency</a></li>
         </ul>
      </li>
      <li><a href="#">Alias</a></li>
      <li><a href="#">Address</a></li>
      <li><a href="#">Alert</a></li>
      <li><a href="#">Contact</a></li>
      <li><a href="#">GP Detail</a></li>
      <li><a href="#">School Detail</a></li>
      <li><a href="#">Other Agency</a></li>
   </ul>
</div>

Где я иду не так?Я не уверен, почему процесс повторяется в конце.Это дополнительный текст, так как stackoverflow не позволяет мне публиковать сообщения, так как требуется больше подробностей.

1 Ответ

0 голосов
/ 24 октября 2018

Проблема с этой строкой ....

 <xsl:apply-templates select="DataRow[not(DataRow/parentid_visio)]"/>

Это говорит "Выберите любой DataRow, который не имеет DataRow/parentid_visio в качестве ребенка".Но ни один DataRow в вашем XML даже не имеет DataRow как дочерний элемент, поэтому он выбирает все строки.

Итак, вы можете изменить его на этот, поэтому он просто проверяет parentid_visio какchild:

 <xsl:apply-templates select="DataRow[not(parentid_visio)]"/>

Но это не сработает, потому что это проверяет существование узла, независимо от того, есть ли у этого текста текст или нет, поэтому <parentid_visio></parentid_visio> возвращает true, и строк нетвыбраны.

Вы должны сделать это, чтобы также проверить пустые parentid_visio узлы и те, которые не существуют

<xsl:apply-templates select="DataRow[not(parentid_visio) or parentid_visio = '']"/>

Или это будет делать то же самое

<xsl:apply-templates select="DataRow[not(parentid_visio != '')]"/>

Или, если бы вы знали, что parentid_visio всегда будет существовать ...

<xsl:apply-templates select="DataRow[parentid_visio = '']"/>

(В этом последнем случае, если parentid_visio не существует в XML, то parentid_visio = '' возвращает falseи поэтому строка не будет выделена).

...