XSLT Установить значения атрибутов из другого файла XML в разных элементах - PullRequest
0 голосов
/ 25 июня 2018

Это немного сложно объяснить, поэтому я говорю на XML ..

XML-файл, который я хочу преобразовать

<Items>
<Item ID="1" Name="Student">
  <Cell Name=""/>
  <Cell Number=""/>
</Item>
<Item ID="1" Name="Professor">
  <Cell Name=""/>
  <Cell Number=""/>
</Item>

values.xml со всеми значениями атрибутов

<students>
  <count>2</count>
    <student number="1">
      <name>Peter</name>
      <number>1234</number>
    </student>
    <student number="2">
      <name>Stefan</name>
      <number>4567</number>
    </student>
</students>

желаемый вывод

    <Items>
        <Item ID="1" Name="Student">
            <Cell Name="Max"/>
            <Cell Number="1234"/>
        </Student>
        <Item ID="2" Name=Student>
            <Cell Name="Stefan"/>
            <Cell Number="4567"/>
        </Professor>
    </Items>

Моя идея

    <xsl:variable name="total" select="document('values.xml')"/>

    <!-- Identity Transformation --> ||WORKS FINE||

    <!-- copy students n-times --> ||WORKS FINE||

<!-- set attribute: name --> ||DOESN'T WORK|| 
<xsl:template match="v:Items/Item/Cell[1]">
<xsl:param name="c" select="1"/>
<xsl:param name="values" select="$total/students/student[@number=$c]"/>    
    <xsl:copy>          
        <xsl:attribute name="Name">
                <xsl:copy-of select="$values/name"/>
            </xsl:attribute>                
            <xsl:apply-templates/>
    </xsl:copy>             
    <xsl:if test="$c &lt; $total/students/count">
        <xsl:apply-templates select=".">
            <xsl:with-param name="c" select="$c+1"/>                        
        </xsl:apply-templates>          
    </xsl:if>       
</xsl:template>

Я получаю оба значения атрибута в каждом элементе.Но мне нужно первое значение атрибута в первом (Cell-) элементе, второе значение атрибута во втором (Cell-) элементе и т. Д.

1 Ответ

0 голосов
/ 25 июня 2018

РЕДАКТИРОВАТЬ: более короткий способ достичь этого - подсчитать позицию в XML и использовать ее для получения индекса Cell и student.

.
<xsl:template match="Items/Item">
    <xsl:variable name="idx"><xsl:number /></xsl:variable>  <!-- index of this 'Item' -->
    <xsl:variable name="values" select="$total/student[@number=$idx]"/> 
    <xsl:copy>          
        <xsl:copy-of select="@*" />                         <!-- copy attributes of this 'Item' -->
        <xsl:apply-templates select="Cell">                 
            <xsl:with-param name="cell" select="$values" /> <!-- pass current 'student' as parameter -->
        </xsl:apply-templates>
    </xsl:copy>             
</xsl:template>

<xsl:template match="Cell">
    <xsl:param name="cell" />
    <xsl:variable name="idx" select="position()" />
    <xsl:variable name="firstAttr" select="name(@*[1])" />  <!-- get the name of the first attribute of this 'Cell' -->
    <xsl:copy>          
        <xsl:attribute name="{$firstAttr}">                 <!-- recreate attribute -->
            <xsl:value-of select="$cell/*[$idx]"/>          <!-- use position() of this 'Cell' as index in the current 'student' -->
        </xsl:attribute>        
    </xsl:copy>             
</xsl:template>

Второй шаблон помещает дочерний элемент nth текущего student в первый атрибут nth Cell.

Если вы хотите соответствовать только учащемуся Cell с, вы можете использовать пустой шаблон, чтобы отфильтровать 'Профессор' Item s:

<xsl:template match="Items/Item[@Name='Professor']" />    

Затем ограничьте первый шаблон сверху предикатом:

<xsl:template match="Items/Item[@Name='Student']">
   <xsl:variable name="idx" select="@ID"></xsl:variable>
   ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...