предшествующий брат с поворотом - PullRequest
0 голосов
/ 23 июня 2010

В примере XML есть две формы, которые совпадают по числу и типу;во второй соответствующей форме мне нужно исключить значение элемента flag.Я не могу изменить уровень, который я повторяю, из-за некоторых взаимосвязанных таблиц стилей.Я могу сделать preceding-sibling, если я итерировал на formslist, но я не могу получить правильный синтаксис, когда я на один уровень глубже в элементе flag.И номер, и тип должны совпадать, прежде чем его убрать.

<apply-templates match="formslist/flag">  
<xsl:choose>
    <xsl:when test=""></xsl:when>
</xsl:choose>
</apply-templates>

Пример XML

<forms>
    <formslist>
        <number>one</number>
        <type>car</type>
        <flag>da</flag>
    </formslist>
    <formslist>
        <number>two</number>
        <type>truck</type>
        <flag>ex</flag>
    </formslist>
    <formslist>
        <number>one</number>
        <type>car</type>
        <flag>da</flag>
    </formslist>
</forms>

Ответы [ 2 ]

1 голос
/ 23 июня 2010

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

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

 <xsl:key name="kFlag" match="formslist/flag"
  use="concat(../number, '+', ../type)"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "flag/text()[generate-id(..)
           !=
            generate-id(key('kFlag',
                            concat(../../number,
                                   '+',
                                   ../../type
                                   )
                            )[1]
                        )
            ]
 "/>
</xsl:stylesheet>

при применении к предоставленному XML-документу :

<forms>
    <formslist>
        <number>one</number>
        <type>car</type>
        <flag>da</flag>
    </formslist>
    <formslist>
        <number>two</number>
        <type>truck</type>
        <flag>ex</flag>
    </formslist>
    <formslist>
        <number>one</number>
        <type>car</type>
        <flag>da</flag>
    </formslist>
</forms>

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

<forms>
   <formslist>
      <number>one</number>
      <type>car</type>
      <flag>da</flag>
   </formslist> 
   <formslist>
      <number>two</number>
      <type>truck</type>
      <flag>ex</flag>
   </formslist>
   <formslist>
      <number>one</number>
      <type>car</type>
      <flag/>
   </formslist>
</forms>

Обратите внимание на использование метода Мюнхена для группировки, который значительно быстрее, чем при сравнении с preceding-sibling::* (последний имеет O(N^2) - квадратичное исполнение).

0 голосов
/ 23 июня 2010

При оценке внутри совпадения шаблона для flag это должно выполнить то, что вы ищете:

    <xsl:variable name="thisFormslist" select=".." />
    <flag>
        <xsl:choose>
            <xsl:when test="../preceding-sibling::*[$thisFormslist/number=number and $thisFormslist/type=type]">
                <!--number and type have been seen before, so don't put a value for this flag-->
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </flag>

Создает переменную для ссылки на текущий элемент formslist и затем использует ее вфильтр предикатов для сравнения number и type с preceding-sibling элементами родительского элемента (formslist).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...