XSLT несколько узлов с одинаковым именем одного уровня - PullRequest
2 голосов
/ 28 июля 2010

У меня есть следующий XML-документ:

<ReportParameters SP="prRptActivityDetail">
    <Parameter>
        <Name>Period Start Date</Name>
        <Type>Date</Type>
        <Control>DateTextbox</Control>
        <ControlName>dtePeriodStartDate</ControlName>
        <Validators>
            <Validator>Required</Validator>
            <Validator>DataTypeCheck</Validator>
            <Validator>StartBeforeEnd</Validator>
        </Validators>
    </Parameter>
</ReportParameters>

Я написал XSLT-файл для преобразования вышеупомянутого:

<xsl:for-each select="ReportParameters/Parameter/Validators">
   <xsl:choose>
       <xsl:when test="Validator='Required'">
           <span>
               <REQUIRED VALIDATOR CONTROL HERE>
           </span>
       </xsl:when>
       <xsl:when test="Validator='DataTypeCheck'">
           <span>
               <DATA TYPE CHECK VALIDATOR CONTROL HERE>
           </span>
       </xsl:when>
   </xsl:choose>

Я упустил много XSLT дляЯсность.

Для каждого элемента управления параметром (в данном случае Дата начала периода) я хочу, чтобы все перечисленные валидаторы (в данном случае 3) были размещены на странице как элементы управления валидатора, но я получаю только первыйпри использовании для каждого.Я знаю, почему это так, но я новичок в xslt и не знаю синтаксиса, чтобы обойти это.

Любая помощь высоко ценится,

Богат.

Ответы [ 4 ]

2 голосов
/ 28 июля 2010

Я думаю, проблема в том, что вы перебираете коллекцию 'Validators'.Вы хотите перебрать все экземпляры Validator.

Попробуйте: ( пример, который я использовал в исследовании )

<xsl:for-each select="ReportParameters/Parameter/Validators/Validator">
   <xsl:choose>
       <xsl:when test=".='Required'">
           <span>
               <REQUIRED VALIDATOR CONTROL HERE>
           </span>
       </xsl:when>
       <xsl:when test=".='DataTypeCheck'">
           <span>
               <DATA TYPE CHECK VALIDATOR CONTROL HERE>
           </span>
       </xsl:when>
   </xsl:choose>
1 голос
/ 28 июля 2010

Я бы предложил заменить ваш <xsl:for-each тег на:

<xsl:apply-templates select="ReportParameters/Parameter/Validators/Validator" />

и включите шаблоны для каждого:

<xsl:template match="Validator[text()='Required']">
  ...
</xsl:template>

<xsl:template match="Validator[text()='DataTypeCheck']">
  ..
</xsl:template>

 etc.

Как сказал @kniemczak, в данный момент вы фактически просматриваете только родительский элемент.

1 голос
/ 28 июля 2010

При изучении XSLT полезно знать, что следует избегать использования <xsl:for-each>, если это действительно не нужно.

Вот простой и короткий способ «без петель» для достижения того же в чистом стиле push:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:variable name="vrtfValidatorNames">
  <validator type="Required" name="REQUIRED"/>
  <validator type="DataTypeCheck" name="DATA TYPE CHECK"/>
  <validator type="StartBeforeEnd" name="START BEFORE END"/>
 </xsl:variable>

 <xsl:variable name="vValidatorNames" select=
  "document('')/*/xsl:variable[@name='vrtfValidatorNames']/*"/>

 <xsl:template match="Validator">
   &lt;<xsl:value-of select="$vValidatorNames[@type=current()]/@name"/> VALIDATOR CONTROL HERE>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

, когда это преобразование применяется к предоставленному документу XML :

<ReportParameters SP="prRptActivityDetail">
    <Parameter>
        <Name>Period Start Date</Name>
        <Type>Date</Type>
        <Control>DateTextbox</Control>
        <ControlName>dtePeriodStartDate</ControlName>
        <Validators>
            <Validator>Required</Validator>
            <Validator>DataTypeCheck</Validator>
            <Validator>StartBeforeEnd</Validator>
        </Validators>
    </Parameter>
</ReportParameters>

желаемый результат получается :

   <REQUIRED VALIDATOR CONTROL HERE>

   <DATA TYPE CHECK VALIDATOR CONTROL HERE>

   <START BEFORE END VALIDATOR CONTROL HERE>
0 голосов
/ 28 июля 2010

Для такого рода задач вам не нужно явно зацикливаться на элементах.Это не способ XSLT.Думайте больше с точки зрения соответствия с древовидной структурой.

Примерно так будет работать:

<xsl:if test="ReportParameters/Parameter/Validators/Validator='Required'">
    <span>
        <REQUIRED></REQUIRED>
     </span>
</xsl:if>
<xsl:if test="ReportParameters/Parameter/Validators/Validator='DataTypeCheck'">
    <span>
        <DATA></DATA>
    </span>
</xsl:if>

Также обратите внимание на создание sub <xsl:template> s и вызов их с <xsl:apply-templates> для обработки небольших частей дерева.Для большого преобразования это должно быть намного более легко обслуживаемым.

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