XSLT Разбор нескольких вложенных детей с помощью тега id - PullRequest
2 голосов
/ 24 августа 2011

У меня есть следующий xml, который мне нужно проанализировать в пары имя / значение, используя XSLT.Неважно, что я пытаюсь, я не могу понять это правильно.Я знаю, что у вас не может быть глобального "счетчика" для отслеживания пакетов, но я пробовал рекурсивные шаблоны, вызывая вспомогательный класс java, position (), count, вы называете его ... Я застрял.

«Пакеты» должны быть пронумерованы одинаково для всех включенных дочерних элементов.

Вот мой фрагмент XML:

<extendedDataElements name="Feed" type="string">
<children name="fileId" type="string">
      <values>TXT123</values>
</children>

<children name="processedTime" type="dateTime">
      <values>2011-07-08T20:15:38</values>
</children>

<children name="batch" type="string">
    <values>0000001</values>
    <children name="statusCode" type="string">
        <values>new</values>
    </children>
</children> 

<children name="batch" type="string">
    <values>0000002</values>
    <children name="statusCode" type="string">
        <values>start</values>
    </children>       
</children>

<children name="batch" type="string">
    <values>0000003</values>
    <children name="statusCode" type="string">
        <values>new</values>
     </children>
</children>

<children name="count" type="long">
      <values>26</values>
</children>
<children name="value" type="double">
      <values>83171.650</values>
</children>
</extendedDataElements>

Вот что мне нужно:

fileID=TXT123, processedTime=2011-07-08T20:15:38, batch1=0000001, statusCode1=new, batch2=0000002, statusCode2=start, batch3=0000003, statusCode3=new, count=26, value=83171.650

Ответы [ 2 ]

1 голос
/ 24 августа 2011

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

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

 <xsl:template match="children">
         <xsl:if test="not(position()=1)">, </xsl:if>
         <xsl:value-of select="concat(@name,'=',values)"/>
 </xsl:template>

 <xsl:template match="children[@name='batch']">
  <xsl:variable name="vNum">
   <xsl:number count="children[@name='batch']" level="single"/>
  </xsl:variable>

         <xsl:if test="not(position()=1)">, </xsl:if>
  <xsl:value-of select="concat('batch', $vNum, '=', values)"/>

  <xsl:apply-templates select="children"/>
 </xsl:template>

 <xsl:template match=
  "children[@name='batch']/children">

  <xsl:variable name="vNum">
    <xsl:for-each select="..">
      <xsl:number count="children[@name='batch']" level="single"/>
     </xsl:for-each>
  </xsl:variable>

  <xsl:value-of select=
    "concat(', ',@name,$vNum,'=',values)"/>
 </xsl:template>
</xsl:stylesheet>

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

<extendedDataElements name="Feed" type="string">
    <children name="fileId" type="string">
        <values>TXT123</values>
    </children>
    <children name="processedTime" type="dateTime">
        <values>2011-07-08T20:15:38</values>
    </children>
    <children name="batch" type="string">
        <values>0000001</values>
        <children name="statusCode" type="string">
            <values>new</values>
        </children>
    </children>
    <children name="batch" type="string">
        <values>0000002</values>
        <children name="statusCode" type="string">
            <values>start</values>
        </children>
    </children>
    <children name="batch" type="string">
        <values>0000003</values>
        <children name="statusCode" type="string">
            <values>new</values>
        </children>
    </children>
    <children name="count" type="long">
        <values>26</values>
    </children>
    <children name="value" type="double">
        <values>83171.650</values>
    </children>
</extendedDataElements>

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

fileId=TXT123, processedTime=2011-07-08T20:15:38, batch1=0000001, statusCode1=new, batch2=0000002, statusCode2=start, batch3=0000003, statusCode3=new, count=26, value=83171.650

Пояснение : хорошее использование следующих основных функций XSLT:

  1. Шаблоны исопоставление с образцом .

  2. <xsl:number>

1 голос
/ 24 августа 2011

Вы можете использовать функцию XPath number(), чтобы переименовать пары пакетов. Например, XPath number('0000001')=1. Вместе с XPath concat() они помогут вам собрать необходимые пары пакетов.

Для обработки запятой я выбрал метод шаблонного режима, но вы можете использовать его по своему усмотрению.

[XSLT 1.0]

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

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

    <xsl:template match="children[not(@name='batch')]">
        <xsl:value-of select="concat(
            @name,'=',values)"/>
        <xsl:apply-templates select="self::*[following-sibling::*]" 
            mode="comma"/>
    </xsl:template>

    <xsl:template match="children[@name='batch']">
        <xsl:value-of select="concat(
            @name,number(values),'=',values,', ',
            children/@name,number(values),'=',children/values)"/>
        <xsl:apply-templates select="self::*[following-sibling::*]" 
            mode="comma"/>
    </xsl:template>

    <xsl:template match="children" mode="comma">
        <xsl:value-of select="', '"/>
    </xsl:template>

</xsl:stylesheet>

с выводом:

fileId=TXT123, processedTime=2011-07-08T20:15:38, batch1=0000001, statusCode1=new, batch2=0000002, statusCode2=start, batch3=0000003, statusCode3=new, count=26, value=83171.650
...