2016-07-08 3 views
0

Я пытаюсь преобразовать XML и разделить третий App_Data значение элемента в несколько повторяющихся строк на основе запятых от:Сплит конкретный элемент атрибута в несколько рядов на основе разделителей

<Metadata> 
     <App_Data App="VOD" Name="Run_Time" Value="01:30:57"/> 
     <App_Data App="VOD" Name="Year" Value="2016"/> 
     <App_Data App="VOD" Name="Category" Value="2330, 2470, 1373"/> 
    </Metadata> 

выглядеть точно так, как это:

<Metadata> 
     <App_Data App="VOD" Name="Run_Time" Value="01:30:57"/> 
     <App_Data App="VOD" Name="Year" Value="2016"/> 
     <App_Data App="VOD" Name="Category" Value="2330"/> 
     <App_Data App="VOD" Name="Category" Value="2470"/> 
     <App_Data App="VOD" Name="Category" Value="1373"/> 
    </Metadata> 

Пожалуйста, помогите.

Спасибо!

+0

ARE YOU используя XSLT 1.0 или 2.0? - P.S. Сделайте поиск * tokenize *. –

+0

@ michael.hor257k благодарит за быстрый ответ! Я использую пример 1.0 в этом примере, однако он только делает атрибуты в дочерние элементы, когда мне нужны атрибуты. http://stackoverflow.com/questions/544336/how-do-i-explode-an-attribute-with-values-separated-by-a-into-seperate-element –

ответ

1

это только делает признаки на ребенок -элементы, когда мне нужно атрибуты

На самом деле, ваш пример показывает, что вам нужен элемент для каждых маркеров.

Попробуй так:

XSLT 1,0

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

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

<xsl:template match="App_Data[@Name='Category']"> 
    <xsl:call-template name="tokenize"> 
     <xsl:with-param name="text" select="@Value"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="tokenize"> 
    <xsl:param name="text"/> 
    <xsl:param name="delimiter" select="', '"/> 
     <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" /> 
     <xsl:if test="$token"> 
      <App_Data App="{@App}" Name="Category" Value="{$token}"/> 
     </xsl:if> 
     <xsl:if test="contains($text, $delimiter)"> 
      <!-- recursive call --> 
      <xsl:call-template name="tokenize"> 
       <xsl:with-param name="text" select="substring-after($text, $delimiter)"/> 
      </xsl:call-template> 
     </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

Или, если вы предпочитаете более короткий (но не многоразовый) версия:

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

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

<xsl:template match="App_Data[@Name='Category']" name="tokenize"> 
    <xsl:param name="text" select="@Value"/> 
    <xsl:param name="delimiter" select="', '"/> 
     <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" /> 
     <xsl:if test="$token"> 
      <App_Data App="{@App}" Name="Category" Value="{$token}"/> 
     </xsl:if> 
     <xsl:if test="contains($text, $delimiter)"> 
      <!-- recursive call --> 
      <xsl:call-template name="tokenize"> 
       <xsl:with-param name="text" select="substring-after($text, $delimiter)"/> 
      </xsl:call-template> 
     </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 
+0

Спасибо! Оно работало завораживающе. Я знаю, что это не имеет значения, кроме одной маленькой вещи: как я могу сохранить элементы для завершения на одной линии, то есть против . –

+0

Я не уверен, что понимаю проблему. Ваш результат отличается от вашего: http://xsltransform.net/jyRYYjq? –

+0

@ michal.hor257k Извините, Майкл никогда не думал, что это проблема с моим скриптом vba, спасибо вам большое! –

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