Создать PDF с отдельной таблицей для тегов с тем же именем - PullRequest
0 голосов
/ 29 января 2019

Я пишу xslt-файл, используя xsl fo для создания pdf-документа с таблицей.У меня есть XML-файл с несколькими тегами с тем же именем. Пример DataContainer:

<tns:StructureData>
    <tns:DataContainer>
        <qwe:Data>
            <asd:Name>Data1 1</asd:Name>
            <asd:Value>100</asd:Value>
            <qwe:Data>
                 <asd:Name>Data1 Inner 1</asd:Name>
                 <asd:Value>1000000</asd:Value>
            </qwe:Data>
        </qwe:Data>
        <qwe:Data>
            <asd:Name>Data1 2</asd:Name>
            <asd:Value>200</asd:Value>
        </qwe:Data>
        <qwe:Data>
            <asd:Name>Data1 3</asd:Name>
            <asd:Value>300</asd:Value>
        </qwe:Data>
        <qwe:Data>
            <asd:Name>Data1 4</asd:Name>
            <asd:Value>400</asd:Value>
        </qwe:Data>
    </tns:DataContainer>

    <tns:DataContainer>
        <qwe:Data>
            <asd:Name>Data2 1</asd:Name>
            <asd:Value>45</asd:Value>
        </qwe:Data>
        <qwe:Data>
            <asd:Name>Data2 2</asd:Name>
            <asd:Value>55</asd:Value>
        </qwe:Data>
        <qwe:Data>
            <asd:Name>Data2 3</asd:Name>
            <asd:Value>65</asd:Value>
        </qwe:Data>
        <qwe:Data>
            <asd:Name>Data2 4</asd:Name>
            <asd:Value>75</asd:Value>
        </qwe:Data>
    </tns:DataContainer>
</tns:StructureData>

И я хочу создать две таблицы для обоих тегов DataContaienr, например:

<table>
  <tr>
    <th>Name</th>
    <th>Value</th> 
  </tr>
  <tr>
    <td>Data1 1</td>
    <td>100</td> 
  </tr>
  <tr>
    <td>Data1 Inner 1</td>
    <td>1000000</td> 
  </tr>
  <tr>
    <td>Data1 2</td>
    <td>200</td> 
  </tr>
  <tr>
    <td>Data1 3</td>
    <td>300</td> 
  </tr>
  <tr>
    <td>Data1 4</td>
    <td>400</td> 
  </tr>
</table>

<table>
  <tr>
    <th>Name</th>
    <th>Value</th> 
  </tr>
  <tr>
    <td>Data2 1</td>
    <td>45</td> 
  </tr>
  <tr>
    <td>Data2 2</td>
    <td>55</td> 
  </tr>
  <tr>
    <td>Data2 3</td>
    <td>65</td> 
  </tr>
  <tr>
    <td>Data2 4</td>
    <td>75</td> 
  </tr>
</table>

Я написал этот xslt:

    <xsl:template match="/">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:layout-master-set>
        <fo:simple-page-master master-name="simpleA4" page-height="30cm" page-width="24cm" margin-top="2cm" margin-bottom="2cm" margin-left="1cm" margin-right="1cm">
          <fo:region-body/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="simpleA4">
        <fo:flow flow-name="xsl-region-body">
            <fo:block font-size="10pt" font-family="Arial">
                <xsl:apply-templates select="/tns:StructureData/tns:DataContainer"/>
            </fo:block>
        </fo:flow>
      </fo:page-sequence>
     </fo:root>
</xsl:template>

<xsl:template match="/tns:StructureData/tns:DataContainer">
  <fo:table table-layout="fixed" width="100%">                    
    <fo:table-column column-width="3cm" />
    <fo:table-column column-width="10cm" />
    <fo:table-header>
        <fo:table-row border-width="1px" border-style="solid">
            <fo:table-cell xsl:use-attribute-sets="marginColumnStyle">
                 <fo:block font-weight="bold">Name</fo:block>
            </fo:table-cell>
            <fo:table-cell xsl:use-attribute-sets="marginColumnStyle">
                 <fo:block font-weight="bold">Value</fo:block>
            </fo:table-cell>
        </fo:table-row>
    </fo:table-header>
    <fo:table-body>
        <xsl:apply-templates select="/tns:StructureData/tns:DataContainer//*[contains(name(), 'qwe:')]"/>
    </fo:table-body>
  </fo:table>
</xsl:template>

<xsl:template match="/tns:StructureData/tns:DataContainer//*[contains(name(), 'qwe:')]">
    <fo:table-row border-width="1px" border-style="solid">    
        <fo:table-cell>
            <fo:block>
                <xsl:value-of select="current()/asd:name"/>
            </fo:block>
        </fo:table-cell> 
        <fo:table-cell xsl:use-attribute-sets="centerCellStyle">
            <fo:block>
                <xsl:value-of select="current()/asd:value"/>
            </fo:block>
        </fo:table-cell>                
    </fo:table-row>
</xsl:template>

Но я получаю две таблицы с данными из двух тегов DataContainer.Результат после выполнения над файлом xslt:

    <table>
  <tr>
    <th>Name</th>
    <th>Value</th> 
  </tr>
  <tr>
    <td>Data1 1</td>
    <td>100</td> 
  </tr>
  <tr>
    <td>Data1 Inner 1</td>
    <td>1000000</td> 
  </tr>
  <tr>
    <td>Data1 2</td>
    <td>200</td> 
  </tr>
  <tr>
    <td>Data1 3</td>
    <td>300</td> 
  </tr>
  <tr>
    <td>Data1 4</td>
    <td>400</td> 
  </tr>
   <tr>
    <th>Name</th>
    <th>Value</th> 
  </tr>
  <tr>
    <td>Data2 1</td>
    <td>45</td> 
  </tr>
  <tr>
    <td>Data2 2</td>
    <td>55</td> 
  </tr>
  <tr>
    <td>Data2 3</td>
    <td>65</td> 
  </tr>
  <tr>
    <td>Data2 4</td>
    <td>75</td> 
  </tr>
</table>

<table>
  <tr>
    <th>Name</th>
    <th>Value</th> 
  </tr>
  <tr>
    <td>Data1 1</td>
    <td>100</td> 
  </tr>
  <tr>
    <td>Data1 Inner 1</td>
    <td>1000000</td> 
  </tr>
  <tr>
    <td>Data1 2</td>
    <td>200</td> 
  </tr>
  <tr>
    <td>Data1 3</td>
    <td>300</td> 
  </tr>
  <tr>
    <td>Data1 4</td>
    <td>400</td> 
  </tr>
  <tr>
    <td>Data2 1</td>
    <td>45</td> 
  </tr>
  <tr>
    <td>Data2 2</td>
    <td>55</td> 
  </tr>
  <tr>
    <td>Data2 3</td>
    <td>65</td> 
  </tr>
  <tr>
    <td>Data2 4</td>
    <td>75</td> 
  </tr>
</table>

Как получить отдельную таблицу для любого тега DataContainer?Я пытаюсь сделать это несколькими способами, но ни один из них не решил мою проблему.

1 Ответ

0 голосов
/ 29 января 2019

Вы, вероятно, хотите заменить эту строку ....

<xsl:apply-templates select="/tns:StructureData/tns:DataContainer//*[contains(name(), 'qwe:')]"/>

На эту строку ....

 <xsl:apply-templates select=".//*[contains(name(), 'qwe:')]"/>

Или, еще лучше ...

 <xsl:apply-templates select=".//qwe:*"/>

В первом случае вы выбираете дочерние элементы всех элементов DataContainer в документе, тогда как во втором случае вы выбираете только потомков DataContainer, с которым вы в настоящее время совпадаете.

Кроме того, вам не обязательно указывать полный путь к элементу в сопоставлении с шаблоном (если только этот элемент не может встречаться на разных уровнях в документе, а вы просто хотите нацелить его на заданный элемент).place)

Итак, этот шаблон соответствует ...

 <xsl:template match="/tns:StructureData/tns:DataContainer">

Можно упростить до этого ...

<xsl:template match="tns:DataContainer">

См. упрощенную версию на http://xsltfiddle.liberty -development.net / 6r5Gh2L

...