XSL根据属性创建文件夹

时间:2011-06-14 16:21:31

标签: xslt

我正在使用XSL将XML转换为KML,以便在Google地球中查看。我将能够为下面的XML示例中的每个“IT_Type”创建文件夹

目前,XML正在转换为这样的文件夹结构:

    • VSS1
    • VSS2
    • CAB1
    • CAB2
    • DMS1
    • DMS2
  • 线
    • 从:
    • 来自:收件人:
    • 从:

需要将其结构化为这样的文件夹,并在Point and Line父文件夹下为每个IT_Type创建一个文件夹。

    • VSS
      • VSS1
      • VSS2
      • CAB1
      • CAB2
    • DMS
      • DMS1
      • DMS2
  • 线
    • 手孔
      • 从:
      • 从:
    • 其他
      • 从:

为此设置XSL的最佳方法是什么?性能是否会成为大型数据集的问题?

感谢任何建议或代码示例。

谢谢。

请参阅下面的示例XML

<Parents>
  <Point>
    <Row IT_ID="116" IT_Name="VSS1" IT_Type="VSS" GPSLat="43.953000000000" GPSLong="-85.671800000000" />
    <Row IT_ID="117" IT_Name="VSS2" IT_Type="VSS" GPSLat="43.966900000000" GPSLong="-85.678900000000" />
    <Row IT_ID="122" IT_Name="Cab1" IT_Type="Cabinet" GPSLat="43.903100000000" GPSLong="-85.677100000000" />
    <Row IT_ID="123" IT_Name="Cab2" IT_Type="Cabinet" GPSLat="43.913500000000" GPSLong="-85.677300000000" />
    <Row IT_ID="254" IT_Name="DMS1" IT_Type="DMS" GPSLat="43.903100000000" GPSLong="-85.677100000000" />
    <Row IT_ID="255" IT_Name="DMS2" IT_Type="DMS" GPSLat="43.989400000000" GPSLong="-85.676800000000" />
  </Point>
  <Line>
    <Row LINE_ID="1117" IT_Type="Handhole" FROM_SYSTEM_ID="2127" TO_SYSTEM_ID="1947" FromLat="43.438474034300" FromLong="-83.195331982500" ToLat="43.437072542900" ToLong="-83.193657308800">
      <Row2 LINE_ID="1117" CONDUIT_NUMBER="1" CONDUIT_TYPE="Fiber" FIBER_NUMBER="1" FIBER_TYPE="Trunk" STRANDS="96" />
      <Row2 LINE_ID="1117" CONDUIT_NUMBER="2" CONDUIT_TYPE="Empty" FIBER_NUMBER="" FIBER_TYPE="" STRANDS="" />
      <Row2 LINE_ID="1117" CONDUIT_NUMBER="3" CONDUIT_TYPE="Empty" FIBER_NUMBER="" FIBER_TYPE="" STRANDS="" />
      <Row2 LINE_ID="1117" CONDUIT_NUMBER="4" CONDUIT_TYPE="Empty" FIBER_NUMBER="" FIBER_TYPE="" STRANDS="" />
    </Row>
    <Row LINE_ID="997" IT_Type="Cabinet" FROM_SYSTEM_ID="2011" TO_SYSTEM_ID="2012" FromLat="43.482705558800" FromLong="-83.260130135400" ToLat="43.482694479700" ToLong="-83.260107590500">
      <Row2 LINE_ID="997" CONDUIT_NUMBER="1" CONDUIT_TYPE="Other" FIBER_NUMBER="" FIBER_TYPE="" STRANDS="" />
    </Row>
    <Row LINE_ID="1220" IT_Type="Other" FROM_SYSTEM_ID="2415" TO_SYSTEM_ID="2413" FromLat="43.624664303600" FromLong="-83.086848805700" ToLat="43.624645615600" ToLong="-83.086770805500">
      <Row2 LINE_ID="1220" CONDUIT_NUMBER="1" CONDUIT_TYPE="Fiber" FIBER_NUMBER="1" FIBER_TYPE="Dist" STRANDS="12" />
      <Row2 LINE_ID="1220" CONDUIT_NUMBER="2" CONDUIT_TYPE="Electric" FIBER_NUMBER="" FIBER_TYPE="" STRANDS="" />
    </Row>
  </Line>
</Parents>

请参阅下面的我的XSL:

<xsl:template match="Parents">
  <Folder>
    <name>
      Point
    </name>
    <xsl:for-each select="Point/Row">
      <Placemark>
        <name>
          <xsl:value-of select="@IT_Name"/>
        </name>
        <description>
          <xsl:value-of select="@Location"/>
        </description>
        <styleUrl>
          <xsl:value-of select="concat($hash,@IT_Type)"/>
        </styleUrl>
        <Point>
          <coordinates>
            <xsl:value-of select="@GPSLong"/>,
            <xsl:value-of select="@GPSLat"/>
          </coordinates>
        </Point>
      </Placemark>
    </xsl:for-each>
  </Folder>
  <Folder>
    <name>
      Line
    </name>
    <xsl:for-each select="Line/Row">
      <Placemark>
        <name>
          From: <xsl:value-of select="@FROM_SYSTEM_ID"/> to: <xsl:value-of select="@TO_SYSTEM_ID"/>
        </name>
        <description>
          <xsl:value-of select="@CONDUIT_NUMBER"/>
        </description>
        <styleUrl>
          <xsl:value-of select="concat($hash,@IT_Type)"/>
        </styleUrl>
        <LineString>
          <tessellate>1</tessellate>
          <coordinates>
            <xsl:value-of select="@FromLong"/>,<xsl:value-of select="@FromLat"/>,0 <xsl:value-of select="@ToLong"/>,<xsl:value-of select="@ToLat"/>,0
          </coordinates>
        </LineString>
      </Placemark>
    </xsl:for-each>
  </Folder>
</xsl:template>

1 个答案:

答案 0 :(得分:1)

很抱歉完全修改了您的初始模板,但通常的方法(在XSLT 1.0中)是通过在多级分组上应用Meunchian的方法。在特定情况下,您可以根据xsl:key@IT_Type的父元素的连接来创建Row


例如, XSLT 1.0 (在 Saxon 6.5 下测试)

<xsl:stylesheet 
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="kIT_Type" 
        match="Row" 
        use="concat(
        name(parent::node()),@IT_Type
        )"/>


    <xsl:template match="Parents/*">
        <Folder>
            <name><xsl:value-of select="name()"/></name>
            <xsl:apply-templates select="Row[
                generate-id(.) 
                = 
                generate-id(key('kIT_Type',
                concat(name(parent::node()),@IT_Type))[1])
                    ]"/>
        </Folder>
    </xsl:template>

<xsl:template match="Row">
    <Folder>
        <name><xsl:value-of select="@IT_Type"/></name>
        <xsl:apply-templates select="key('kIT_Type',
            concat(name(parent::node()),@IT_Type))" 
            mode="placemark"/>
    </Folder>
</xsl:template>

    <xsl:template match="Row[parent::Point]" mode="placemark">
        <Placemark>
            <name>
                <xsl:value-of select="@IT_Name"/>
            </name>
            <description>
                <!--xsl:value-of select="@Location"/-->
            </description>
            <styleUrl>
                <!--xsl:value-of select="concat($hash,@IT_Type)"/-->
            </styleUrl>
            <Point>
                <coordinates>
                    <xsl:value-of select="@GPSLong"/>,
                    <xsl:value-of select="@GPSLat"/>
                </coordinates>
            </Point>
        </Placemark>
    </xsl:template>

    <xsl:template match="Row[parent::Line]" mode="placemark">
        <Placemark>
            <name>
                From: <xsl:value-of select="@FROM_SYSTEM_ID"/> to: <xsl:value-of select="@TO_SYSTEM_ID"/>
            </name>
            <description>
                <xsl:value-of select="@CONDUIT_NUMBER"/>
            </description>
            <styleUrl>
                <!-- xsl:value-of select="concat($hash,@IT_Type)"/-->
            </styleUrl>
            <LineString>
                <tessellate>1</tessellate>
                <coordinates>
                    <xsl:value-of select="@FromLong"/>,<xsl:value-of select="@FromLat"/>,0 <xsl:value-of select="@ToLong"/>,<xsl:value-of select="@ToLat"/>,0
                </coordinates>
            </LineString>
        </Placemark>
    </xsl:template>

    <xsl:template match="Row2"/>

</xsl:stylesheet>

应用于您的输入,生成RTF:

<Folder>
   <name>Point</name>
   <Folder>
      <name>VSS</name>
      <Placemark>
         <name>VSS1</name>
         <description/>
         <styleUrl/>
         <Point>
            <coordinates>-85.671800000000,
                    43.953000000000</coordinates>
         </Point>
      </Placemark>
      <Placemark>
         <name>VSS2</name>
         <description/>
         <styleUrl/>
         <Point>
            <coordinates>-85.678900000000,
                    43.966900000000</coordinates>
         </Point>
      </Placemark>
   </Folder>
   <Folder>
      <name>Cabinet</name>
      <Placemark>
         <name>Cab1</name>
         <description/>
         <styleUrl/>
         <Point>
            <coordinates>-85.677100000000,
                    43.903100000000</coordinates>
         </Point>
      </Placemark>
      <Placemark>
         <name>Cab2</name>
         <description/>
         <styleUrl/>
         <Point>
            <coordinates>-85.677300000000,
                    43.913500000000</coordinates>
         </Point>
      </Placemark>
   </Folder>
   <Folder>
      <name>DMS</name>
      <Placemark>
         <name>DMS1</name>
         <description/>
         <styleUrl/>
         <Point>
            <coordinates>-85.677100000000,
                    43.903100000000</coordinates>
         </Point>
      </Placemark>
      <Placemark>
         <name>DMS2</name>
         <description/>
         <styleUrl/>
         <Point>
            <coordinates>-85.676800000000,
                    43.989400000000</coordinates>
         </Point>
      </Placemark>
   </Folder>
</Folder>
<Folder>
   <name>Line</name>
   <Folder>
      <name>Handhole</name>
      <Placemark>
         <name>
                From: 2127 to: 1947</name>
         <description/>
         <styleUrl/>
         <LineString>
            <tessellate>1</tessellate>
            <coordinates>-83.195331982500,43.438474034300,0 -83.193657308800,43.437072542900,0
                </coordinates>
         </LineString>
      </Placemark>
   </Folder>
   <Folder>
      <name>Cabinet</name>
      <Placemark>
         <name>
                From: 2011 to: 2012</name>
         <description/>
         <styleUrl/>
         <LineString>
            <tessellate>1</tessellate>
            <coordinates>-83.260130135400,43.482705558800,0 -83.260107590500,43.482694479700,0
                </coordinates>
         </LineString>
      </Placemark>
   </Folder>
   <Folder>
      <name>Other</name>
      <Placemark>
         <name>
                From: 2415 to: 2413</name>
         <description/>
         <styleUrl/>
         <LineString>
            <tessellate>1</tessellate>
            <coordinates>-83.086848805700,43.624664303600,0 -83.086770805500,43.624645615600,0
                </coordinates>
         </LineString>
      </Placemark>
   </Folder>
</Folder>