2014-01-05 18 views
-2

Ниже код XSLT дает результат по результату сравнения родительского узла. Я ищу результат сравнения дочерних узлов, ожидаемый результат, как показано ниже. Описание: XSLT-код дает родительский узел (сеть A, сеть B и т. Д.), И я хочу, чтобы результат дочернего узла (Network AA, Network AB и т. Д.) Сравнивался. Я предлагаю вам, пожалуйста, проверить входной файл xml и ожидаемый результат, чтобы легко понять мое требование. Пожалуйста, ссылку на ссылку convert XSLT code from version 2.0 to 1.0Как получить дочерние узлы вместо родителя?

Входной XML-файл:

<?xml version="1.0" encoding="utf-8"?> 
<OperatorStationCollection > 
    <OperatorStation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Name>OS001</Name> 
    <Nodes> 
     <DataNodeBase xsi:type="Adaptor"> 
     <Family>NetworkSettings</Family> 
     <Name>Network A</Name> 
     <IPAddress>111.11.11.1</IPAddress> 
     <ChildNodes> 
      <DataNodeChild xsi:type="SubResult"> 
       <Family>NetworkSettings</Family> 
       <Name>Network AA</Name> 
       <IPAddress>111.11.11.12</IPAddress> 
      </DataNodeChild> 
      <DataNodeChild xsi:type="SubResult"> 
       <Family>NetworkSettings</Family> 
       <Name>Network AB</Name> 
       <IPAddress>111.11.11.13</IPAddress> 
      </DataNodeChild>    
     </ChildNodes> 
     </DataNodeBase> 
     <DataNodeBase xsi:type="Adaptor"> 
     <Family>NetworkSettings</Family> 
     <Name>Network B</Name> 
     <IPAddress>111.22.11.1</IPAddress> 
     <ChildNodes> 
      <DataNodeChild xsi:type="SubResult"> 
       <Family>NetworkSettings</Family> 
       <Name>Network BA</Name> 
       <IPAddress>111.11.11.21</IPAddress> 
      </DataNodeChild> 
      <DataNodeChild xsi:type="SubResult"> 
       <Family>NetworkSettings</Family> 
       <Name>Network BB</Name> 
       <IPAddress>111.11.11.31</IPAddress> 
      </DataNodeChild>    
     </ChildNodes> 
     </DataNodeBase>  
    </Nodes> 
    </OperatorStation> 
    <OperatorStation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Name>OS002</Name> 
    <Nodes> 
     <DataNodeBase xsi:type="Adaptor"> 
     <Family>NetworkSettings</Family> 
     <Name>Network A</Name> 
     <IPAddress>111.11.11.1</IPAddress> 
     <ChildNodes> 
      <DataNodeChild xsi:type="SubResult"> 
       <Family>NetworkSettings</Family> 
       <Name>Network AA</Name> 
       <IPAddress>111.11.11.12</IPAddress> 
      </DataNodeChild> 
      <DataNodeChild xsi:type="SubResult"> 
       <Family>NetworkSettings</Family> 
       <Name>Network AB</Name> 
       <IPAddress>111.11.11.13</IPAddress> 
      </DataNodeChild>    
     </ChildNodes> 
     </DataNodeBase> 
     <DataNodeBase xsi:type="Adaptor"> 
     <Family>NetworkSettings</Family> 
     <Name>Network B</Name> 
     <IPAddress>111.22.11.1</IPAddress> 
     <ChildNodes> 
      <DataNodeChild xsi:type="SubResult"> 
       <Family>NetworkSettings</Family> 
       <Name>Network BA</Name> 
       <IPAddress>111.11.11.12</IPAddress> 
      </DataNodeChild> 
      <DataNodeChild xsi:type="SubResult"> 
       <Family>NetworkSettings</Family> 
       <Name>Network BB</Name> 
       <IPAddress>111.11.11.13</IPAddress> 
      </DataNodeChild>    
     </ChildNodes> 
     </DataNodeBase>  
    </Nodes> 
    </OperatorStation> 
</OperatorStationCollection> 

XSLT файл

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w3="http://www.w3.org"> 
    <xsl:output method="html" indent="yes"/> 

    <xsl:key name="networks" match="w3:DataNodeBase" use="w3:Name"/> 
    <xsl:key name="networksAndIP" match="w3:DataNodeBase" use="concat(w3:Name, '|', w3:IPAddress)"/> 

    <xsl:variable name="allStations" select="//w3:OperatorStation"/> 
    <xsl:variable name="allStationsCount" select="count($allStations)"/> 

    <xsl:template match="/"> 
     <table><!-- Header row - two fixed columns plus one per station name --> 
     <tr> 
      <td>Name</td> 
      <td>Status</td> 
      <xsl:for-each select="$allStations"> 
       <td> 
        <xsl:value-of select="w3:Name"/> 
       </td> 
      </xsl:for-each> 
     </tr> 
     <xsl:apply-templates select="//w3:DataNodeBase[generate-id() = generate-id(key('networks', w3:Name)[1])]"/> 
     </table> 
    </xsl:template> 

    <xsl:template match="w3:DataNodeBase"> 
     <tr> 
     <td> 
      <xsl:value-of select="w3:Name"/> 
     </td> 
     <td> 
      <xsl:choose> 
       <xsl:when test="count(key('networksAndIP', concat(w3:Name, '|', w3:IPAddress))) = $allStationsCount">Equal</xsl:when> 
       <xsl:otherwise>Unequal</xsl:otherwise> 
      </xsl:choose> 
     </td> 
     <xsl:variable name="network" select="w3:Name"/> 
     <xsl:for-each select="$allStations"> 
      <td> 
       <xsl:value-of select="key('networks', $network)[../../w3:Name=current()/w3:Name]/w3:IPAddress"/> 
      </td> 
     </xsl:for-each> 
     </tr> 
    </xsl:template> 
</xsl:stylesheet> 

Ожидаемый ВЫВОД: Поскольку не существует никакого положения, чтобы добавить таблицу, я сделал hatml код результата, сохраните этот код в html-файле и увидите ожидаемый результат. Для понимания, которое я сделал, я сделал таблицу, я ищу вывод в xml, но было бы здорово, если бы кто-нибудь сделал xslt-файл, который дает/показывает результат в табличном формате.

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title></title>  
</head> 
<body> 

    <table> 
      <tr> 
      <td>Name</td><td>Status</td><td>OS01</td><td>OS02</td> 
      </tr> 
      <tr> 
      <td>Network AB</td><td>Equal</td><td>111.11.11.12</td><td>111.11.11.12</td> 
      </tr> 
      <tr> 
      <td>Network AB</td><td>Equal</td><td>111.11.11.13</td><td>111.11.11.13</td> 
      </tr> 
      <tr> 
      <td>Network BA</td><td>Unequal</td><td>111.11.11.21</td><td>111.11.11.12</td> 
      </tr> 
      <tr> 
      <td>Network BB</td><td>Unequal</td><td>111.11.11.31</td><td>111.11.11.13</td> 
      </tr>     
      </table> 

</body> 
</html> 
+3

ИМХО, получив очень похожий вопрос, ответил уже три раза, вы должны уметь это выяснить самостоятельно. –

+0

XSLT - это очень новое для меня, и у меня нет времени изучать его из-за нехватки времени. Я никогда не поднимал вопрос без суда, и даже вы можете видеть, что вопросы похожи, но не легко. Ваша помощь приветствуется в противном случае. все равно. – ADP

+0

Возможный дубликат [Как сравнить два узла XML и получить результат сравнения с помощью XSLT?] (Http://stackoverflow.com/questions/20901103/how-to-compare-two-xml-nodes-and-get-compared- result-use-xslt) –

ответ

0

Прежде чем ответить, я предполагаю, что вы пропустили объявление пространства имен в вашем XML, и что корневой элемент должен выглядеть на самом деле это (если нет, то вам нужно будет удалить все следы имен с помощью XSLT тоже)

<OperatorStationCollection xmlns="http://www.w3.org"> 

в вашем предыдущем вопросе вы группировки по DataNodeBase, но в новом вопросе, вы группирование по DataNodeChild. Это означает, что все, что вам действительно нужно сделать, буквально заменяет все вхождения DataNodeBase на DataNodeChild в вашем XSLT.

Единственное изменение, чтобы сделать это в этой линии

<xsl:value-of 
    select="key('networks', $network)[../../w3:Name=current()/w3:Name]/w3:IPAddress"/> 

Поскольку DataNodeChild вложен еще два уровня сделано, выражение должно быть изменено соответствующим образом

<xsl:value-of 
    select="key('networks', $network)[../../../../w3:Name=current()/w3:Name]/w3:IPAddress"/> 

еще лучше, чтобы справиться с этим на любом уровне, это может быть

<xsl:value-of 
    select="key('networks', $network)[ancestor::w3:OperatorStation/w3:Name=current()/w3:Name]/w3:IPAddress"/> 

И все. Попробуйте это XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w3="http://www.w3.org"> 
    <xsl:output method="html" indent="yes"/> 
    <xsl:key name="networks" match="w3:DataNodeChild" use="w3:Name"/> 
    <xsl:key name="networksAndIP" match="w3:DataNodeChild" use="concat(w3:Name, '|', w3:IPAddress)"/> 
    <xsl:variable name="allStations" select="//w3:OperatorStation"/> 
    <xsl:variable name="allStationsCount" select="count($allStations)"/> 
    <xsl:template match="/"> 
     <table><!-- Header row - two fixed columns plus one per station name --> 
     <tr> 
      <td>Name</td> 
      <td>Status</td> 
      <xsl:for-each select="$allStations"> 
       <td> 
        <xsl:value-of select="w3:Name"/> 
       </td> 
      </xsl:for-each> 
     </tr> 
     <xsl:apply-templates select="//w3:DataNodeChild[generate-id() = generate-id(key('networks', w3:Name)[1])]"/> 
     </table> 
    </xsl:template> 
    <xsl:template match="w3:DataNodeChild"> 
     <tr> 
     <td> 
      <xsl:value-of select="w3:Name"/> 
     </td> 
     <td> 
      <xsl:choose> 
       <xsl:when test="count(key('networksAndIP', concat(w3:Name, '|', w3:IPAddress))) = $allStationsCount">Equal</xsl:when> 
       <xsl:otherwise>Unequal</xsl:otherwise> 
      </xsl:choose> 
     </td> 
     <xsl:variable name="network" select="w3:Name"/> 
     <xsl:for-each select="$allStations"> 
      <td> 
       <xsl:value-of select="key('networks', $network)[ancestor::w3:OperatorStation/w3:Name=current()/w3:Name]/w3:IPAddress"/> 
      </td> 
     </xsl:for-each> 
     </tr> 
    </xsl:template> 
</xsl:stylesheet> 
Смежные вопросы