2014-10-23 3 views
0

Я попытался найти, но подошел пустой. Кажется, это так просто, но я застрял.Выбор одного узла из аналогичных узлов

В основном у меня есть записи, в которых я использовал группировку Muenchian, но мне нужно выбрать только или другое.

Как и в случае ниже: Я хочу только одно появление идентификатора, имеющего имя - синий. Пример ниже должен выбрать ID 1234, который является синим, и игнорировать другой ID 1234 с именем = красный. То же самое с последним ID 5555. Позиция может быть случайной. Для этого мне нужно, чтобы это также было вставлено в формате CSV.

Когда я применить Muenchian группировку по ID, работает с проблемами, пытаясь

Любая помощь будет очень цениться.

<Table> 
<Record> 
    <ID>1234</ID> 
    <Name>Blue</Name> 
    <Status>Available</Status> 
    <Number>111111</Number> 
</Record> 
<Record> 
    <ID>1234</ID> 
    <Name>Red</Name> 
    <Status>Available</Status> 
    <Number>212121</Number> 
</Record> 
<Record> 
    <ID>2222</ID> 
    <Name>Hazel</Name> 
    <Status>Available</Status> 
    <Number>4424233</Number> 
</Record> 
<Record> 
    <ID>3333</ID> 
    <Name>Purple</Name> 
    <Status>Available</Status> 
    <Number>23234</Number> 
</Record> 
<Record> 
    <ID>4444</ID> 
    <Name>Brown</Name> 
    <Status>Available</Status> 
    <Number>76567567</Number> 
</Record> 
<Record> 
    <ID>5555</ID> 
    <Name>Green</Name> 
    <Status>Available</Status> 
    <Number>3456356</Number> 
</Record> 
<Record> 
    <ID>5555</ID> 
    <Name>Blue</Name> 
    <Status>Available</Status> 
    <Number>324342</Number> 
</Record> 

Вывод должен быть:

<Table> 
<Record> 
    <ID>1234</ID> 
    <Name>Blue</Name> 
    <Status>Available</Status> 
    <Number>111111</Number> 
</Record> 
<Record> 
    <ID>2222</ID> 
    <Name>Orange</Name> 
    <Status>Available</Status> 
    <Number>4424233</Number> 
</Record> 
<Record> 
    <ID>3333</ID> 
    <Name>Silver</Name> 
    <Status>Available</Status> 
    <Number>23234</Number> 
</Record> 
<Record> 
    <ID>4444</ID> 
    <Name>Blue</Name> 
    <Status>Available</Status> 
    <Number>76567567</Number> 
</Record> 
<Record> 
    <ID>5555</ID> 
    <Name>Blue</Name> 
    <Status>Available</Status> 
    <Number>3456356</Number> 
</Record> 

Update: Я понял, способ сделать это без использования Muenchian Группировка и работает специально для этого случая. Но мне было интересно, есть ли лучший способ сделать это, и если Muenchian Grouping будет работать. Проблема, с которой я столкнулась с группировкой Muenchian, заключается в том, чтобы определить, на каком этапе группировка была в этом случае первой встречей или секундой.

<?xml version="1.0" encoding="utf-8" ?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" indent="yes" omit-xml-declaration="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:template match="Table"> 
    <xsl:text>IDNumber,Name,Status,Number</xsl:text> 
    <xsl:text>&#xa;</xsl:text> 
     <xsl:for-each select="Record"> 
      <xsl:choose> 
       <xsl:when test="ID = following-sibling::Record[1]/ID and Name = 'Blue'"> 
        <xsl:value-of select="ID"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="Name"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="Status"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="Number"/> 
        <xsl:text>&#xa;</xsl:text> 
       </xsl:when> 
       <xsl:when test="ID = following-sibling::Record[1]/ID and Name != 'Blue' and following-sibling::Record[1]/Name != 'Blue'"> 
        <xsl:value-of select="ID"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="Name"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="Status"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="Number"/> 
        <xsl:text>&#xa;</xsl:text> 
       </xsl:when> 
       <xsl:when test="ID = following-sibling::Record[1]/ID and Name !='Blue'"> 
        <xsl:value-of select="following-sibling::Record[1]/ID"/><xsl:text>,   </xsl:text> 
        <xsl:value-of select="following-sibling::Record[1]/Name"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="following-sibling::Record[1]/Status"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="following-sibling::Record[1]/Number"/> 
        <xsl:text>&#xa;</xsl:text> 
       </xsl:when> 
       <xsl:when test="ID != preceding-sibling::Record[1]/ID"> 
        <xsl:value-of select="ID"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="Name"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="Status"/><xsl:text>,</xsl:text> 
        <xsl:value-of select="Number"/> 
        <xsl:text>&#xa;</xsl:text>       
       </xsl:when> 
       </xsl:choose>    
      </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
+0

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

+0

Позвольте мне посмотреть, могу ли я сделать это более понятным: если существует 2 идентичных идентификатора, мне нужно сохранить узел с именем = «Синий». Тождественные узлы смежны, но узел, содержащий «синий», может быть в первом или втором совпадающем идентификаторе. Если существует только один уникальный идентификатор, я просто его сохраняю. –

+0

. Правильно ли это повторять это как: для каждого уникального идентификатора выведите ровно один узел; если один (или более?) узлов - синий, то выведите этот узел (или первый из этих узлов). –

ответ

0

Если я правильно понимаю, это должно сработать для вас;

XSLT 1.0

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

<xsl:key name="records-by-id" match="Record" use="ID" /> 

<xsl:template match="/Table"> 
    <!-- HEADER --> 
    <xsl:text>IDNumber,Name,Status,Number&#10;</xsl:text> 
    <!-- FOR EACH DISTINCT ID: --> 
    <xsl:for-each select="Record[count(. | key('records-by-id', ID)[1]) = 1]"> 
     <!-- TAKE THE RECORDS IN CURRENT GROUP ... --> 
     <xsl:for-each select="key('records-by-id', ID)"> 
      <!-- .. SORT THEM BY "BLUENESS" ... --> 
      <xsl:sort select="Name='Blue'" data-type="text" order="descending"/> 
      <!-- ... AND OUTPUT THE FIRST RECORD IN THE (SORTED) GROUP --> 
      <xsl:if test="position()=1"> 
       <xsl:call-template name="row"/> 
      </xsl:if> 
     </xsl:for-each> 
     <xsl:if test="position()!=last()"> 
      <xsl:text>&#10;</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

<xsl:template name="row"> 
    <xsl:for-each select="*"> 
     <xsl:value-of select="."/> 
     <xsl:if test="position()!=last()"> 
      <xsl:text>,</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

Применительно к вашему примеру вход, результат:

IDNumber,Name,Status,Number 
1234,Blue,Available,111111 
2222,Hazel,Available,4424233 
3333,Purple,Available,23234 
4444,Brown,Available,76567567 
5555,Blue,Available,324342 
+0

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

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