创建新结构并使用xslt移动元素

时间:2013-07-30 19:15:08

标签: xslt

我有一个格式相当糟糕的输入xml需要使用xslt 1.0进行重组。 必须更改层次结构,以便在上部和下部划分细节线,每个细节线包含左右部分。到目前为止,我无法创建所需的输出。 有人可以帮助我,提前谢谢。

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<document>
<Header_Label_Header_1>
  <Label_Header_Header_Company>1001</Label_Header_Header_Company>
  <Label_Header_Header_Unique_Sequence_Number>1</Label_Header_Header_Unique_Sequence_Number>
    <Detail_Line>
      <Line_Print_Description_1>PAR Wdfl Vivida bianco strukt.</Line_Print_Description_1>
      <Line_Print_Description_2>30x60cm</Line_Print_Description_2>
    </Detail_Line>
    <Detail_Line>
      <Line_Print_Description_1>PAR Wdfl Secret bianco 1.</Line_Print_Description_1>
      <Line_Print_Description_2>29,5x59,5cm</Line_Print_Description_2>
    </Detail_Line>
</Header_Label_Header_1>
<Header_Label_Header_2>
  <Label_Header_Header_Company>00500</Label_Header_Header_Company>
  <Label_Header_Header_Unique_Sequence_Number>2</Label_Header_Header_Unique_Sequence_Number>
    <Detail_Line>
      <Line_Print_Description_1>IRS Fstzg Porcelainw.Brownwood</Line_Print_Description_1>
      <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
    </Detail_Line>
    <Detail_Line>
      <Line_Print_Description_1>IRS Fstzg Porcelainw.Greywood</Line_Print_Description_1>
      <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
    </Detail_Line>
    <Detail_Line>
      <Line_Print_Description_1>IRS Fstzg Porcelainw.Blackwood</Line_Print_Description_1>
      <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
    </Detail_Line>
</Header_Label_Header_2>
<Header_Label_Header_3>
  <Label_Header_Header_Company>00500</Label_Header_Header_Company>
  <Label_Header_Header_Unique_Sequence_Number>3</Label_Header_Header_Unique_Sequence_Number>
    <Detail_Line>
      <Line_Print_Description_1>RAK Fstzg Ardesia black gl.str</Line_Print_Description_1>
      <Line_Print_Description_2>frb, R9, 30x60cm</Line_Print_Description_2>
    </Detail_Line>
</Header_Label_Header_3>
<Header_Label_Header_4>
  <Label_Header_Header_Company>00500</Label_Header_Header_Company>
  <Label_Header_Header_Unique_Sequence_Number>4</Label_Header_Header_Unique_Sequence_Number>
    <Detail_Line>
      <Line_Print_Description_1>BAUMIT KlebeSpachtel 25kg</Line_Print_Description_1>
      <Line_Print_Description_2></Line_Print_Description_2>
    </Detail_Line>
</Header_Label_Header_4>
<Header_Label_Header_1>
  <Label_Header_Header_Company>1001</Label_Header_Header_Company>
  <Label_Header_Header_Unique_Sequence_Number>1</Label_Header_Header_Unique_Sequence_Number>
    <Detail_Line>
      <Line_Print_Description_1>PAR Wdfl Vivida bianco strukt.</Line_Print_Description_1>
      <Line_Print_Description_2>30x60cm</Line_Print_Description_2>
    </Detail_Line>
    <Detail_Line>
      <Line_Print_Description_1>PAR Wdfl Secret bianco 1.</Line_Print_Description_1>
      <Line_Print_Description_2>29,5x59,5cm</Line_Print_Description_2>
    </Detail_Line>
</Header_Label_Header_1>
<Header_Label_Header_2>
  <Label_Header_Header_Company>00500</Label_Header_Header_Company>
  <Label_Header_Header_Unique_Sequence_Number>2</Label_Header_Header_Unique_Sequence_Number>
    <Detail_Line>
      <Line_Print_Description_1>IRS Fstzg Porcelainw.Brownwood</Line_Print_Description_1>
      <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
    </Detail_Line>
    <Detail_Line>
      <Line_Print_Description_1>IRS Fstzg Porcelainw.Greywood</Line_Print_Description_1>
      <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
    </Detail_Line>
    <Detail_Line>
      <Line_Print_Description_1>IRS Fstzg Porcelainw.Blackwood</Line_Print_Description_1>
      <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
    </Detail_Line>
</Header_Label_Header_2>
<Header_Label_Header_3>
  <Label_Header_Header_Company>00500</Label_Header_Header_Company>
  <Label_Header_Header_Unique_Sequence_Number>3</Label_Header_Header_Unique_Sequence_Number>
    <Detail_Line>
      <Line_Print_Description_1>RAK Fstzg Ardesia black gl.str</Line_Print_Description_1>
      <Line_Print_Description_2>frb, R9, 30x60cm</Line_Print_Description_2>
    </Detail_Line>
</Header_Label_Header_3>
<Header_Label_Header_4>
  <Label_Header_Header_Company>00500</Label_Header_Header_Company>
  <Label_Header_Header_Unique_Sequence_Number>4</Label_Header_Header_Unique_Sequence_Number>
    <Detail_Line>
      <Line_Print_Description_1>BAUMIT KlebeSpachtel 25kg</Line_Print_Description_1>
      <Line_Print_Description_2></Line_Print_Description_2>
    </Detail_Line>
</Header_Label_Header_4>
</document>

输出必须如下:

    <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<document>
<Header_Label_Upper>
    <Label_Left>
      <Label_Header_Header_Company>1001</Label_Header_Header_Company>
      <Label_Header_Header_Unique_Sequence_Number>1</Label_Header_Header_Unique_Sequence_Number>
    </Label_Left>
            <Detail_Line_Left>
              <Line_Print_Description_1>PAR Wdfl Vivida bianco strukt.</Line_Print_Description_1>
              <Line_Print_Description_2>30x60cm</Line_Print_Description_2>
            </Detail_Line_Left>
            <Detail_Line_Left>
              <Line_Print_Description_1>PAR Wdfl Secret bianco 1.</Line_Print_Description_1>
              <Line_Print_Description_2>29,5x59,5cm</Line_Print_Description_2>
    </Detail_Line_Left>
    <Label_Right>
      <Label_Header_Header_Company>00500</Label_Header_Header_Company>
      <Label_Header_Header_Unique_Sequence_Number>2</Label_Header_Header_Unique_Sequence_Number>
    </Label_Right>
            <Detail_Line_Right>
              <Line_Print_Description_1>IRS Fstzg Porcelainw.Brownwood</Line_Print_Description_1>
              <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
            </Detail_Line_Right>
            <Detail_Line_Right>
              <Line_Print_Description_1>IRS Fstzg Porcelainw.Greywood</Line_Print_Description_1>
              <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
            </Detail_Line_Right>
            <Detail_Line_Right>
              <Line_Print_Description_1>IRS Fstzg Porcelainw.Blackwood</Line_Print_Description_1>
              <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
            </Detail_Line_Right>
</Header_Label_Upper>
<Header_Label_Lower>
    <Label_Left>
      <Label_Header_Header_Company>00500</Label_Header_Header_Company>
      <Label_Header_Header_Unique_Sequence_Number>3</Label_Header_Header_Unique_Sequence_Number>
    </Label_Left>
            <Detail_Line_Left>
              <Line_Print_Description_1>RAK Fstzg Ardesia black gl.str</Line_Print_Description_1>
              <Line_Print_Description_2>frb, R9, 30x60cm</Line_Print_Description_2>
            </Detail_Line_Left>
    <Label_Right>
      <Label_Header_Header_Company>00500</Label_Header_Header_Company>
      <Label_Header_Header_Unique_Sequence_Number>4</Label_Header_Header_Unique_Sequence_Number>
    </Label_Right>
            <Detail_Line_Right>
              <Line_Print_Description_1>BAUMIT KlebeSpachtel 25kg</Line_Print_Description_1>
              <Line_Print_Description_2></Line_Print_Description_2>
            </Detail_Line_Right>
</Header_Label_Lower>
<Header_Label_Upper>
    <Label_Left>
      <Label_Header_Header_Company>1001</Label_Header_Header_Company>
      <Label_Header_Header_Unique_Sequence_Number>1</Label_Header_Header_Unique_Sequence_Number>
    </Label_Left>
            <Detail_Line_Left>
              <Line_Print_Description_1>PAR Wdfl Vivida bianco strukt.</Line_Print_Description_1>
              <Line_Print_Description_2>30x60cm</Line_Print_Description_2>
            </Detail_Line_Left>
            <Detail_Line_Left>
              <Line_Print_Description_1>PAR Wdfl Secret bianco 1.</Line_Print_Description_1>
              <Line_Print_Description_2>29,5x59,5cm</Line_Print_Description_2>
    </Detail_Line_Left>
    <Label_Right>
      <Label_Header_Header_Company>00500</Label_Header_Header_Company>
      <Label_Header_Header_Unique_Sequence_Number>2</Label_Header_Header_Unique_Sequence_Number>
    </Label_Right>
            <Detail_Line_Right>
              <Line_Print_Description_1>IRS Fstzg Porcelainw.Brownwood</Line_Print_Description_1>
              <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
            </Detail_Line_Right>
            <Detail_Line_Right>
              <Line_Print_Description_1>IRS Fstzg Porcelainw.Greywood</Line_Print_Description_1>
              <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
            </Detail_Line_Right>
            <Detail_Line_Right>
              <Line_Print_Description_1>IRS Fstzg Porcelainw.Blackwood</Line_Print_Description_1>
              <Line_Print_Description_2>frb. R9, 15x120cm</Line_Print_Description_2>
            </Detail_Line_Right>
</Header_Label_Upper>
<Header_Label_Lower>
    <Label_Left>
      <Label_Header_Header_Company>00500</Label_Header_Header_Company>
      <Label_Header_Header_Unique_Sequence_Number>3</Label_Header_Header_Unique_Sequence_Number>
    </Label_Left>
            <Detail_Line>
              <Line_Print_Description_1>RAK Fstzg Ardesia black gl.str</Line_Print_Description_1>
              <Line_Print_Description_2>frb, R9, 30x60cm</Line_Print_Description_2>
            </Detail_Line>
    <Label_Right>
      <Label_Header_Header_Company>00500</Label_Header_Header_Company>
      <Label_Header_Header_Unique_Sequence_Number>4</Label_Header_Header_Unique_Sequence_Number>
    </Label_Right>
            <Detail_Line>
              <Line_Print_Description_1>BAUMIT KlebeSpachtel 25kg</Line_Print_Description_1>
              <Line_Print_Description_2></Line_Print_Description_2>
            </Detail_Line>
</Header_Label_Lower>
</document>

1 个答案:

答案 0 :(得分:1)

给出您的示例XML,以下XSL:

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

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

      <!-- Match the root node. -->
      <xsl:template match="document">
        <xsl:copy>
          <!-- Restructure each subset of four Header_Label_Header elements. -->
          <xsl:for-each select="*[position() mod 4 = 1]">
            <xsl:call-template name="subset">
              <xsl:with-param name="subset-nodes" select=". | following-sibling::*[position() &lt; 4]"/>
            </xsl:call-template>
          </xsl:for-each>
        </xsl:copy>
      </xsl:template>

      <xsl:template name="subset">
        <xsl:param name="subset-nodes"/>
        <!-- Select the first and third elements and give them appropriate upper/lower labels. -->
        <xsl:for-each select="$subset-nodes[position() mod 2 = 1]">
          <xsl:choose>
            <xsl:when test="position() = 1">
              <Header_Label_Upper>
                <!-- Select this element and the one that follows it. -->
                <xsl:apply-templates select=". | following-sibling::*[position() &lt; 2]"/>
              </Header_Label_Upper>
            </xsl:when>
            <xsl:otherwise>
              <Header_Label_Lower>
                <!-- Select this element and the one that follows it. -->
                <xsl:apply-templates select=". | following-sibling::*[position() &lt; 2]"/>
              </Header_Label_Lower>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
      </xsl:template>

  <!-- Match the Header_Label_Header elements and give them appropriate left/right labels. -->
  <xsl:template match="*[contains(local-name(), 'Header_Label_Header_')]">
    <xsl:choose>
      <xsl:when test="position() = 1">
        <Label_Left>
          <xsl:apply-templates select="*[contains(local-name(), 'Label_Header_Header_')]"/>
        </Label_Left>
        <xsl:apply-templates select="Detail_Line" mode="Left"/>
      </xsl:when>
      <xsl:otherwise>
        <Label_Right>
          <xsl:apply-templates select="*[contains(local-name(), 'Label_Header_Header_')]"/>
        </Label_Right>
        <xsl:apply-templates select="Detail_Line" mode="Right"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="Detail_Line" mode="Left">
    <Detail_Line_Left>
      <xsl:apply-templates/>
    </Detail_Line_Left>  
  </xsl:template>

  <xsl:template match="Detail_Line" mode="Right">
    <Detail_Line_Right>
      <xsl:apply-templates/>
    </Detail_Line_Right>
  </xsl:template>
</xsl:stylesheet>

输出所需的XML。

模板可能会有所改进,因为有一些重复的代码,但它可以完成这项工作。