2016-12-03 2 views
0

Я новичок в XSLT 2.0, и мне нужно преобразовать XML в текстовый файл (CSV), но я хочу, чтобы результат находился в порядке атрибута строки (см. Ниже XML, таблица стилей и вывод). Как видите, вывод строки = "9" должен быть второй строкой. Вопрос в том, как изменить таблицу стилей для достижения правильного вывода?преобразование XML в текст (csv-файл) сортировка по атрибуту

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <MP>   
     <CSVIMP line="10" content="xyz"/> 
     <CSVIMP line="11" content="123"/> 
     <CSVIMP line="8" content="123"/> 
    </MP> 
    <MP> 
     <CSVIMP line="9" content="abc"/> 
     <CSVIMP line="12" content="456"/> 
    </MP> 
</root> 

Моя таблица стилей:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="text" encoding="UTF-8" /> 

    <xsl:variable name="delimiter" select="','"/> 

    <xsl:template match="MP"> 
     <xsl:for-each select="CSVIMP"> 
      <xsl:sort select="./@line" data-type="number"></xsl:sort> 
      <xsl:value-of select="./@line"/> 
      <xsl:value-of select="$delimiter"/> 
      <xsl:value-of select="./@content"/> 
      <xsl:text>&#10;</xsl:text> 
     </xsl:for-each> 
    </xsl:template> 

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

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

Преобразованный выход (Saxon 9,5 HE):

8,123 
10,xyz 
11,123 
9,abc 
12,456 

ответ

1

Трудно точно сказать, что вы хотите, не видя ожидаемого выхода. Так как вы говорите, что «выход линии =» 9" должна быть вторая линия, я предполагаю, что вы хотите сделать это (и только это):

<xsl:template match="/root"> 
    <xsl:for-each select="MP/CSVIMP"> 
     <xsl:sort select="./@line" data-type="number"></xsl:sort> 
     <xsl:value-of select="./@line"/> 
     <xsl:value-of select="$delimiter"/> 
     <xsl:value-of select="./@content"/> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

И так как вы используете XSLT 2.0, вы могли бы, вероятно, * сократить все, что нужно:

XSLT 2,0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text" encoding="UTF-8" /> 

<xsl:template match="/root"> 
    <xsl:for-each select="MP/CSVIMP"> 
     <xsl:sort select="./@line" data-type="number"/> 
     <xsl:value-of select="@line, @content" separator=","/> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

(*) при условии, всеЭлементыимеют оба атрибута.

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