У меня есть набор данных XML (предоставленный из SharePoint 2007 в DVWP), структурированный примерно так:
<Rows>
<Row ID="1" Spanoffset="0" Span="55" Spantail="55"/>
<Row ID="2" Spanoffset="30" Span="31" Spantail="61"/>
<Row ID="3" Spanoffset="61" Span="20" Spantail="81"/>
<Row ID="4" Spanoffset="82" Span="30" Spantail="112"/>
</Rows>
Скажем, каждая строка представляет собой полосу, которая начинается с @Spanoffset
и имеет ширину @Span
, @Spantail
есть, поэтому мне не нужно вычислять ее, если она мне нужна. Я пытаюсь эффективно упаковать строки вместе, чтобы строки, которые не перекрываются, группировались вместе. Набор данных предварительно отсортирован по @Spanoffset
. По сути, это задача о рюкзаке, поскольку каждый ряд может входить в несколько возможных групп. Я хочу сделать простое жадное решение и знаю, как я могу его закодировать, скажем, на C # или java, но поскольку я не могу пометить узлы как посещенные (ну, я могу, но я теряю его, когда возвращаюсь к дереву рекурсии) и я не могу удалить узлы, когда посещаю их, я не понимаю, как к этому подойти.
Например, приведенные выше данные будут выглядеть примерно так:
<div style="clear:both">
<div style="width: 110px; margin-left: 0px; float:left;">1</div>
<div style="width: 40px; margin-left: 12px; float:left;">3</div>
<div style="width: 60px; margin-left: 2px; float:left;">4</div>
</div>
<div style="clear:both">
<div style="width: 62px; margin-left: 60px; float:left;">2</div>
</div>
Я не утруждала себя попытками заставить поплавки работать правильно, так как мне еще не удалось заставить узлы Row
появляться только по одному разу каждый в правильном порядке. Как только я получу их там, я почти уверен, что смогу заставить форматирование работать.
Лучший XSLT, который я придумал, был:
<xsl:template match="row">
<xsl:variable name="tail" select="@Spantail"/>
<div style="width:{2*@Span}px;
left:{2*(@Spanoffset)}px;">
<xsl:value-of select="@ID"/>
</div>
<xsl:apply-templates select="(following-sibling::row)[@Spanoffset>=$tail][1]"/>
</xsl:template>
Что порождает
<div style="width: 110px;left: 0px">1</div>
<div style="width: 40px; left: 122px">3</div>
<div style="width: 60px; left: 164px">4</div>
<div style="width: 62px; left: 60px">2</div>
<div style="width: 40px; left: 122px">3</div>
<div style="width: 60px; left: 164px">4</div>
<div style="width: 40px; left: 122px">3</div>
<div style="width: 60px; left: 164px">4</div>
<div style="width: 60px; left: 164px">4</div>
Итак, у меня две проблемы (которые я вижу), и я думаю, что они взаимосвязаны. 1) Как исправить / перефакторить мой шаблон (ы), чтобы выдавать каждую строку только один раз. и 2) Как обернуть группы в контейнер <div>
элементов.
Бился головой об это 2 дня, кто-нибудь может помочь?
Изменить: Ну, после некоторого сна у меня есть контейнер для упаковки, добавив логический параметр в мой шаблон и используя некоторые теги CDATA
для испускания тегов <div>
, когда он истинен. По умолчанию логическое значение имеет значение true, и когда я вызываю вложенные шаблоны apply, я устанавливаю его значение false, тем самым упаковывая группы в контейнеры. Я все еще не вижу способа отметить <Row>
как посещенные.
<Row ID="1" Spanoffset="0" Span="10" Spantail="10"/>
,<Row ID="2" Spanoffset="15" Span="10" Spantail="25"/>
,<Row ID="3" Spanoffset="20" Span="10" Spantail="35"/>
. Сгруппировали бы вы строки 1 и 2 вместе или строки 1 и 3 вместе? - person Ben L   schedule 19.11.2013