Экспорт данных из аналогичных узлов в Xml, чтобы преуспеть, используя Xslt - PullRequest
0 голосов
/ 15 марта 2011

У меня есть XML-документ, в котором значения генерируются динамически, и мне нужно экспортировать эти данные в Excel, используя xslt. Для тестирования я создал образец xml: -

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ucdetector>
  <!--COPY_RIGHT-->
  <statistics/>
  <markers>
    <!--Sample XML_INFO-->
    <marker>
      <description>Desc</description>
      <classRef>Test1</classRef>
      <classRef>Test2</classRef>
      <classRef>Test3</classRef>
      <markerType>Class PreferenceInitializer has 8 references</markerType>
    </marker>
  </markers>
  <problems/>
</ucdetector>

xslt выглядит следующим образом: -

= tab = новая строка ->

<!-- First line: about -->
<xsl:value-of
    select="concat('Report', '&#x9;', /ucdetector/statistics/abouts/about[@name='reportCreated']/value, '&#xA;', '&#xA;')" />
<!-- Second line: header -->

<xsl:value-of
    select="concat('Class Name', '&#x9;', 'Referring class
    name', '&#x9;', 'Class Details', '&#xA;')" />


<xsl:for-each select="/ucdetector/markers/marker">
    <xsl:variable name="vars">
        <xsl:apply-templates select="classRef" />
    </xsl:variable>
    <xsl:value-of
        select="concat(description, '&#x9;', $vars, '&#x9;', markerType, '&#xA;')" />
</xsl:for-each>

Мне удалось правильно экспортировать все данные в Excel, за исключением данных в теге "classRef", который отображается вместе как "Test1Test2Test3", но они мне нужны отдельно в разных столбцах Excel. Кто-нибудь может дать некоторую подсказку по этому поводу?

Ответы [ 2 ]

0 голосов
/ 16 марта 2011

Ваш вопрос немного неясен. Я думаю, что вы пытаетесь сделать, это выдать текст всех дочерних элементов элемента marker, разделенных табуляцией, в виде строки текста, оканчивающейся новой строкой. Это правильно?

Если это так, я не вижу никакой пользы от создания переменной, содержащей элементы classRef, все соединенные вместе - вы не относитесь к ним иначе, чем к другим элементам. Вы можете просто использовать простой шаблон для преобразования каждого элемента marker в строку вывода:

 <!-- It's really only worth doing this if your transform uses lots of tabs
      and newlines, which this one no longer does.  But it aids readability
      and reduces the number of typos you'll make, so it's a good habit to
      get into. -->
 <xsl:variable name="tab">&#x9</xsl:variable>
 <xsl:variable name="newline">&#xA;</xsl:variable>

 <xsl:template match="marker">
    <xsl:for-each select="*">
      <xsl:if test="position() != 1">
        <xsl:value-of select="$tab"/>
      </xsl:if>
      <xsl:value-of select="."/>
    </xsl:for-each>
    <xsl:value-of select="$newline"/>
 </xsl:template>

Edit:

Хорошо, пример, который вы опубликовали, проясняет, что вы ищете. То, что вы хотите, это одна строка в выводе для каждого элемента classRef, а не для каждого элемента marker. Каждая строка должна иметь одинаковое количество вкладок и заканчиваться символом новой строки. Но строка first для любого данного элемента marker должна содержать данные для не classRef элементов, в то время как остальные строки должны содержать данные только для элементов classRef.

Это должно сработать:

<xsl:template match="marker">
   <xsl:apply-templates select="classRef"/>
</xsl:template>

<xsl:template match="classRef[position() = 1]">
   <xsl:variable name="current" select="."/>
   <xsl:for-each select="../*[name() != 'classRef' or . = $current]">
      <xsl:if test="position() != 1">
         <xsl:value-of select="$tab"/>
      </xsl:if>
      <xsl:value-of select="."/>
   </xsl:for-each>
   <xsl:value-of select="$newline"/>
</xsl:template>

<xsl:template match="classRef">
   <xsl:variable name="current" select="."/>
   <xsl:for-each select="../*[name() != 'classRef' or . = $current]">
      <xsl:if test="position() != 1">
         <xsl:value-of select="$tab"/>
      </xsl:if>
      <xsl:if test=". = $current">
         <xsl:value-of select="."/>
      </xsl:if>
   </xsl:for-each>
   <xsl:value-of select="$newline"/>
</xsl:template>
0 голосов
/ 16 марта 2011

Полагаю, вы хотите, чтобы три значения были разделены табуляцией? В этом случае я был бы склонен сделать это (в XSLT 2.0)

<xsl:for-each select="/ucdetector/markers/marker">
    <xsl:variable name="vars">
        <xsl:value-of select="classRef" separator="'&#x9;'"/>
    </xsl:variable>
    <xsl:value-of
        select="concat(description, '&#x9;', $vars, '&#x9;', markerType, '&#xA;')" />
</xsl:for-each>

или в 1,0

<xsl:for-each select="/ucdetector/markers/marker">
    <xsl:variable name="vars">
        <xsl:for-each select="classRef">
          <xsl:if test="position()!=1"><xsl:text>&#x9;</xsl:text></xsl:if>
          <xsl:value-of select="."/>
        </xsl:for-each>
    </xsl:variable>
    <xsl:value-of
        select="concat(description, '&#x9;', $vars, '&#x9;', markerType, '&#xA;')" />
</xsl:for-each>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...