2015-04-22 7 views
0

я должен был бы преобразовать этот входной XML:XSLT1 Трансформация

<Log1> 
    <Connection User="Peter" Host="Computer01" Port="22"/> 
    <Connection User="Peter" Host="Computer02" Port="22"/> 
    <Connection User="Peter" Host="Computer02" Port="80"/> 
    <Connection User="David" Host="Computer01" Port="8080"/> 
    <Connection User="David" Host="Computer01" Port="8080"/> 
    <Connection User="David" Host="Computer01" Port="8080"/> 
    <Connection User="David" Host="Computer03" Port="22"/> 
    <Connection User="David" Host="Computer04" Port="21"/> 
</Log1> 

В этот выходной XML:

<Log2> 
    <Event Name="David" Target="Computer01|Computer03|Computer04"/> 
    <Event Name="Peter" Target="Computer01|Computer02"/>    
</Log2> 

До сих пор я использовал Muenchian группировку и получили что-то вроде:

<Log2>  
    <Event Name="David" Target="Computer01|Computer01|Computer01|Computer03|Computer04"/> 
    <Event Name="Peter" Target="Computer01|Computer02|computer02"/> 
</Log2> 

Проблема в том, что я не могу избавиться от дубликатов машин в моем выпуске.

Вот мой XSLT:

<xsl:key name="myKey" match="Connection" use="@User"/> 
<xsl:variable name="separator" select="'|'"/> 

<xsl:template match="Log1"> 
    <xsl:element name="Log2">  
     <xsl:for-each select="Connection[count(. | key('myKey', @User)[1]) = 1]"> 
      <xsl:sort select="@User" /> 
      <xsl:element name="Event"> 
       <xsl:attribute name="Name"> 
        <xsl:value-of select="@User" /> 
       </xsl:attribute> 
       <xsl:attribute name="Target"> 
        <xsl:for-each select="key('myKey', @User)"> 
         <xsl:sort select="@Host" /> 
         <xsl:value-of select="@Host" /> 
         <xsl:if test="position() != last()"> 
          <xsl:value-of select="$separator" />    
         </xsl:if> 
        </xsl:for-each> 
       </xsl:attribute> 
      </xsl:element> 
     </xsl:for-each>   
    </xsl:element> 
</xsl:template> 

Не могли бы вы, ребята, помогите мне с помощью XSLT 1.0 процессор?

+1

Пожалуйста, покажите текущую таблицу стилей XSLT. –

+0

Текущий XSLT добавлен, огромное спасибо! – nereide

ответ

1

Вам действительно нужно сделать второй набор Muenchian grouping здесь, потому что вам также необходимо сгруппировать по комбинации «Пользователь» и «Хост», чтобы получить отдельный атрибут Host для каждого пользователя. Итак, вам нужен второй ключ, как так:

<xsl:key name="myKey2" match="Connection" use="concat(@User, '|', @Host)"/> 

(Обратите внимание, что труба | может быть что-нибудь здесь, так долго, как это не происходит в любом User или Host).

И затем вы используете в своей внутренней xsl:for-each так:

<xsl:for-each select="key('myKey', @User)[count(. | key('myKey2', concat(@User, '|', @Host))[1]) = 1]"> 

Попробуйте XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:key name="myKey" match="Connection" use="@User"/> 
<xsl:key name="myKey2" match="Connection" use="concat(@User, '|', @Host)"/> 
<xsl:variable name="separator" select="'|'"/> 

<xsl:template match="Log1"> 
    <xsl:element name="Log2">  
     <xsl:for-each select="Connection[count(. | key('myKey', @User)[1]) = 1]"> 
      <xsl:sort select="@User" /> 
      <xsl:element name="Event"> 
       <xsl:attribute name="Name"> 
        <xsl:value-of select="@User" /> 
       </xsl:attribute> 
       <xsl:attribute name="Target"> 
        <xsl:for-each select="key('myKey', @User)[count(. | key('myKey2', concat(@User, '|', @Host))[1]) = 1]"> 
         <xsl:sort select="@Host" /> 
         <xsl:value-of select="@Host" /> 
         <xsl:if test="position() != last()"> 
          <xsl:value-of select="$separator" />    
         </xsl:if> 
        </xsl:for-each> 
       </xsl:attribute> 
      </xsl:element> 
     </xsl:for-each>   
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

Как примечание стороны, нет никакой необходимости использовать xsl:element для создания элементов с использованием статического имена, просто напишите элемент напрямую. Например

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

<xsl:key name="myKey" match="Connection" use="@User"/> 
<xsl:key name="myKey2" match="Connection" use="concat(@User, '|', @Host)"/> 
<xsl:variable name="separator" select="'|'"/> 

<xsl:template match="Log1"> 
    <Log2>  
     <xsl:for-each select="Connection[count(. | key('myKey', @User)[1]) = 1]"> 
      <xsl:sort select="@User" /> 
      <Event Name="{@User}"> 
       <xsl:attribute name="Target"> 
        <xsl:for-each select="key('myKey', @User)[count(. | key('myKey2', concat(@User, '|', @Host))[1]) = 1]"> 
         <xsl:sort select="@Host" /> 
         <xsl:value-of select="@Host" /> 
         <xsl:if test="position() != last()"> 
          <xsl:value-of select="$separator" />    
         </xsl:if> 
        </xsl:for-each> 
       </xsl:attribute> 
      </Event> 
     </xsl:for-each>   
    </Log2> 
</xsl:template> 
</xsl:stylesheet> 

отметить также использование шаблонов значений атрибутов в создании атрибута Name.

+0

Привет, Тим, я просто проверил ваш XSLT, и он работает как шарм! Большое спасибо! – nereide

Смежные вопросы