XSL для создания папок на основе атрибута - PullRequest
2 голосов
/ 14 июня 2011

Я использую XSL для преобразования XML в KML для просмотра в Google Earth.Я хотел бы иметь возможность создавать папки для каждого "IT_Type" в примере XML ниже

В настоящее время XML преобразуется в структуру папок, например:

  • Точка
    • VSS1
    • VSS2
    • Cab1
    • Cab2
    • DMS1
    • DMS2
  • Линия
    • С: Кому:
    • С: Кому:
    • С: Кому:

Требуетсябыть структурированным в такие папки, с папкой для каждого IT_Type в родительских папках Point и Line.

  • Point
    • 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 Ответ

1 голос
/ 14 июня 2011

Извините, что полностью пересмотрел ваш первоначальный шаблон, но наиболее распространенный способ сделать это (в 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...