2010-08-10 4 views
2

У меня есть следующий xml, который нужно преобразовать. Но я не понимаю, как получить первичное значение тега драйвера в преобразованном xml. Первичный драйвер должен основываться на позиции узлов драйвера. Может кто-нибудь мне помочь?Позиция родительского элемента xslt

<drivers> 
    <driver> 
    <first_name>Doug</first_name> 
    <last_name>Harry</last_name> 
    <vehicles> 
    <vehicle> 
    <vin>4T1BB46K08</vin> 
    <year>2008</year> 
    </vehicle> 
     </vehicles> 
     <records/> 
    </driver> 
    <driver> 
     <first_name>Sherry</first_name> 
     <last_name>Bloom</last_name> 
     <vehicles> 
      <vehicle> 
       <vin>5TDZA23C06</vin> 
       <year>2006</year> 
      </vehicle> 
     </vehicles> 
     <records/> 
    </driver> 
</drivers> 

Результат должен быть

<Vehicles> 
    <vehicle> 
    <vin>4T1BB46K08</vin> 
    <year>2008</year> 
    <primarydriver>1</primarydriver> 
    </vehicle> 
    <vehicle> 
    <vin>5TDZA23C06</vin> 
    <year>2006</year> 
    <primarydriver>2</primarydriver> 
    </vehicle> 
</Vehicles> 
+0

Не могли бы вы переформатировать XML, чтобы быть более читабельными? – developer

+0

Я не могу отформатировать это. Любая помощь будет оценена по достоинству. – Amzath

+0

Вы не определили, что такое «основной драйвер» ??? Является ли это первым драйвером в документе со значением VIN? Если это так, ваш XML-документ не является репрезентативным: есть только два драйвера, и каждый из них имеет другой VIN, поэтому оба они являются основными драйверами. Вам необходимо опубликовать документ XML, в котором некоторые драйверы не должны быть помечены в результате в качестве основных драйверов. –

ответ

1

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

<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:template match="node()|@*"> 
    <xsl:param name="pDriverPos"/> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*"> 
    <Vehicles> 
    <xsl:apply-templates/> 
    </Vehicles> 
</xsl:template> 

<xsl:template match="driver"> 
    <xsl:apply-templates> 
    <xsl:with-param name="pDriverPos" select="position()"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="vehicles"> 
    <xsl:param name="pDriverPos"/> 

    <xsl:apply-templates> 
    <xsl:with-param name="pDriverPos" select="$pDriverPos"/> 
    </xsl:apply-templates> 
</xsl:template> 

<xsl:template match="vehicle"> 
    <xsl:param name="pDriverPos"/> 

    <vehicle> 
    <xsl:apply-templates/> 
    <primarydriver><xsl:value-of select="$pDriverPos"/></primarydriver> 
    </vehicle> 
</xsl:template> 

<xsl:template match="first_name|last_name|records"/> 
</xsl:stylesheet> 

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

<drivers> 
    <driver> 
    <first_name>Doug</first_name> 
    <last_name>Harry</last_name> 
    <vehicles> 
    <vehicle> 
    <vin>4T1BB46K08</vin> 
    <year>2008</year> 
    </vehicle> 
     </vehicles> 
     <records/> 
    </driver> 
    <driver> 
     <first_name>Sherry</first_name> 
     <last_name>Bloom</last_name> 
     <vehicles> 
      <vehicle> 
       <vin>5TDZA23C06</vin> 
       <year>2006</year> 
      </vehicle> 
     </vehicles> 
     <records/> 
    </driver> 
</drivers> 

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

<Vehicles> 
    <vehicle> 
     <vin>4T1BB46K08</vin> 
     <year>2008</year> 
     <primarydriver>1</primarydriver> 
    </vehicle> 
    <vehicle> 
     <vin>5TDZA23C06</vin> 
     <year>2006</year> 
     <primarydriver>2</primarydriver> 
    </vehicle> 
</Vehicles> 

Заметьте: Использование измененного правила идентификации с параметром, который передает текущую позицию водителя. Это значительно более эффективно, чем подсчет предыдущих братьев и сестер.

0

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="drivers"> 
     <Vehicles> 
      <xsl:apply-templates/> 
     </Vehicles> 
    </xsl:template> 
    <xsl:template match="driver|driver/*|driver/*/text()"> 
     <xsl:apply-templates/> 
    </xsl:template> 
    <xsl:template match="vehicle/*[last()]"> 
     <xsl:call-template name="identity"/> 
     <primarydriver> 
      <xsl:value-of select="count(preceding::driver)+1"/> 
     </primarydriver> 
    </xsl:template> 
</xsl:stylesheet> 

Выход:

<Vehicles> 
    <vehicle> 
     <vin>4T1BB46K08</vin> 
     <year>2008</year> 
     <primarydriver>1</primarydriver> 
    </vehicle> 
    <vehicle> 
     <vin>5TDZA23C06</vin> 
     <year>2006</year> 
     <primarydriver>2</primarydriver> 
    </vehicle> 
</Vehicles> 

Примечание: Counting предшествующее.

Смежные вопросы