XSLT - Чтобы избежать дублирования значений [duplicate]

Это означает, что указанная переменная не указана ни на что. Я мог бы сгенерировать это так:

SqlConnection connection = null;
connection.Open();

Это вызовет ошибку, потому что, пока я объявил переменную «connection», она не указала ни на что. Когда я пытаюсь вызвать член «Open», для его устранения нет ссылки, и он будет вызывать ошибку.

Чтобы избежать этой ошибки:

  1. Всегда инициализируйте свои объекты, прежде чем пытаться что-либо с ними делать.
  2. Если вы не уверены, что объект имеет значение null, проверьте его с помощью object == null.

Инструмент Resharper JetBrains определит каждое место в вашем коде, которое имеет возможность ошибки нулевой ссылки, позволяя вам ввести нулевую проверку. Эта ошибка является источником ошибок номер один, IMHO.

3
задан Daniel 19 August 2010 в 03:58
поделиться

3 ответа

Это преобразование:

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

 <xsl:key name="kwrkTimeByNameTask" match="workTime"
  use="concat(../name, '+', @taskID)"/>

 <xsl:key name="kDateByName" match="date"
  use="../name"/>

 <xsl:key name="kwrkTimeByNameTaskDate" match="workTime"
  use="concat(../name, '+', @taskID, '+', ../date)"/>

 <xsl:template match="/">
   <xsl:for-each select=
    "*/*/workTime
           [generate-id()
           =
            generate-id(key('kwrkTimeByNameTask',
                             concat(../name, '+', @taskID)
                            )[1]
                        )
           ]
    ">
      <xsl:sort select="../name"/>
      <xsl:sort select="@taskID" data-type="number"/>

      <xsl:variable name="vcurTaskId" select="@taskID"/>
      <Person>
        <name><xsl:value-of select="../name"/></name>
        <taskID><xsl:value-of select="@taskID"/></taskID>

          <xsl:for-each select=
           "key('kDateByName', ../name)
                  [key('kwrkTimeByNameTaskDate',
                       concat(../name, '+', current()/@taskID, '+', .)
                      )
                  ]
           ">
             <workTime>
               <date><xsl:value-of select="."/></date>
               <time>
                <xsl:value-of select=
                 "key('kwrkTimeByNameTaskDate',
                  concat(../name, '+', $vcurTaskId, '+', .)
                 )"/>
               </time>
             </workTime>
          </xsl:for-each>
      </Person>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному XML (исправлено из нескольких проблем, чтобы стать хорошо сформированным):

<t>
    <Person>
        <name>John</name>
        <date>June12</date>
        <workTime taskID="1">34</workTime>
        <workTime taskID="1">35</workTime>
        <workTime taskID="2">12</workTime>
    </Person>
    <Person>
        <name>John</name>
        <date>June13</date>
        <workTime taskID="1">21</workTime>
        <workTime taskID="2">11</workTime>
        <workTime taskID="2">14</workTime>
    </Person>
</t>

создает желаемый, правильный результат :

<Person>
   <name>John</name>
   <taskID>1</taskID>
   <workTime>
      <date>June12</date>
      <time>34</time>
   </workTime>
   <workTime>
      <date>June13</date>
      <time>21</time>
   </workTime>
</Person>
<Person>
   <name>John</name>
   <taskID>2</taskID>
   <workTime>
      <date>June12</date>
      <time>12</time>
   </workTime>
   <workTime>
      <date>June13</date>
      <time>11</time>
   </workTime>
</Person>

Пояснение:

  1. Сначала мы получаем все workTime элементы с уникальными парами ../name, @taskID, используя метод Muenchian для группировки.
  2. Мы сортируем их по ../name и @taskID - в этом порядке.
  3. Для каждого такого workTime мы получаем все date элементы, которые перечислены с ../name этого workTime и оставить только те из этих date элементов, для которых существует workTime, который имеет те же ../date и ../name.
  4. На предыдущем шаге мы используйте два разных вспомогательных ключа: 'kDateByName' индексирует все date элементы по их ../name, а 'kwrkTimeByNameTaskDate' индексирует все workTime элементы по их ../name, их ../date и их @taskID.

Итак, смысл следующего:

          <xsl:for-each select=
           "key('kDateByName', ../name)
                  [key('kwrkTimeByNameTaskDate',
                       concat(../name, '+', current()/@taskID, '+', .)
                      )
                  ]
           ">

:

Для каждого date для [ name, таких, что a workTime для этого name, date и @taskID ( тока workTime для внешнего <xsl:for-each>) существует, делать то, что находится в теле этого <xsl:for-each> инструкция .

2
ответ дан Dimitre Novatchev 26 August 2018 в 16:34
поделиться

Просто для удовольствия, другие решения с двумя ключами. Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kWorkTimeByName-TaskID" match="workTime" 
              use="concat(../name,'++',@taskID)"/>
    <xsl:key name="kWorkTimeByName-Date-TaskID" match="workTime" 
              use="concat(../name,'++',../date,'++',@taskID)"/>
    <xsl:template match="/">
        <xsl:variable name="vAllWorkTime" select="*/*/workTime"/>
        <result>
            <xsl:for-each select="$vAllWorkTime
                        [count(.|key('kWorkTimeByName-TaskID',
                                         concat(../name,'++',@taskID))[1])=1]">
                <xsl:sort select="../name"/>
                <xsl:sort select="@taskID" data-type="number"/>
                <Person>
                    <xsl:copy-of select="../name"/>
                    <taskID>
                        <xsl:value-of select="@taskID"/>
                    </taskID>
                    <xsl:for-each select="$vAllWorkTime
                          [count(.|key('kWorkTimeByName-Date-TaskID',
                               concat(current()/../name,'++',
                                   ../date,'++',current()/@taskID))[1])=1]">
                        <xsl:sort select="../date"/>
                        <xsl:copy>
                            <xsl:copy-of select="../date"/>
                            <time>
                                <xsl:value-of select="."/>
                            </time>
                        </xsl:copy>
                    </xsl:for-each>
                </Person>
            </xsl:for-each>
        </result>
    </xsl:template>
</xsl:stylesheet>

Выход:

<result>
    <Person>
        <name>John</name>
        <taskID>1</taskID>
        <workTime>
            <date>June12</date>
            <time>34</time>
        </workTime>
        <workTime>
            <date>June13</date>
            <time>21</time>
        </workTime>
    </Person>
    <Person>
        <name>John</name>
        <taskID>2</taskID>
        <workTime>
            <date>June12</date>
            <time>12</time>
        </workTime>
        <workTime>
            <date>June13</date>
            <time>11</time>
        </workTime>
    </Person>
</result>
1
ответ дан user 26 August 2018 в 16:34
поделиться

Группировка в XSLT обычно выполняется с использованием метода, называемого методом Muenchian. Подробнее здесь: http://www.jenitennison.com/xslt/grouping/muenchian.html

0
ответ дан Wilfred Springer 26 August 2018 в 16:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: