开发者

XSL to create folders based on attribute

开发者 https://www.devze.com 2023-03-13 03:21 出处:网络
I am using XSL to transform XML to KML to be viewed in Google Earth. I would to be able to create folders for each \"IT_Type\" in the XML sample below

I am using XSL to transform XML to KML to be viewed in Google Earth. I would to be able to create folders for each "IT_Type" in the XML sample below

Currently, the XML is being transformed into a folder structure like this:

  • Point
    • VSS1
    • VSS2
    • Cab1
    • Cab2
    • DMS1
    • DMS2
  • Line
    • From:To:
    • From:To:
    • From:To:

It needs to be structured into folders like this, with a folder for each IT_Type under the Point and Line parent folders.

  • Point
    • VSS
      • VSS1
      • VSS2
    • Cabinet
      • Cab1
      • Cab2
    • DMS
      • DMS1
      • DMS2
  • Line
    • Handhole
      • From:To:
    • Cabinet
      • From:To:
    • Other
      • From:To:

What is the best way to go about setting up the XSL for this? Will performance be an issue on large data sets?

Any advice or code sample is appreciated.

Thank you.

Please see below for sample 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>

Please see below for my 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>
          <c开发者_如何学运维oordinates>
            <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>


Sorry for having completely revised your initial template, but the common way to do this (in XSLT 1.0) is by applying Meunchian's method on a multi-level grouping. In your specific case, you can create a xsl:key based on concatenation of @IT_Type and the parent element of Row.


For instance, this XSLT 1.0 (tested under 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>

Applied on your input, produces the 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>
0

精彩评论

暂无评论...
验证码 换一张
取 消