Преобразование XML в XML с использованием XSL - PullRequest
2 голосов
/ 03 января 2012

Мне нужно преобразовать данные XML в другой формат. Я сделал очень мало XSL, и мой поиск в интернете не дал мне необходимых результатов. У меня есть этот образец XML:

 <MailStatusReport>
        <Output>
            <ColMetaData ColCount="5">
                <ColList>
                    <Col  Name="parcelid" Pos="1"/>
                    <Col  Name="currentlocationid" Pos="2"/>
                    <Col  Name="deliverystatus" Pos="4"/>
                    <Col  Name="requestedlocationid" Pos="3"/>
                    <Col  Name="requestor" Pos="5"/>
                </ColList>
            </ColMetaData>
            <RowList>
                <Row>
                    <ColList>
                        <Col Pos="2">Delaware</Col>
                        <Col Pos="1">001</Col>
                        <Col Pos="3">NewYork</Col>
                        <Col Pos="4">InRoute</Col>
                        <Col Pos="5">John</Col>

                    </ColList>
                </Row>
                <Row>
                    <ColList>
                        <Col Pos="1">002</Col>
                        <Col Pos="2">Sanjose</Col>
                        <Col Pos="3">Michigan</Col>
                        <Col Pos="4">Delivered</Col>
                        <Col Pos="5">Rob</Col>
                    </ColList>
                </Row>
            </RowList>
        </Output>
</MailStatusReport>

Желаемый вывод:

   <MailStatusReport>
        <Row parcelid="001" currentlocationid="Delaware" requestedlocationid="NewYork" deliverystatus="InRoute" requestor="John"/>
        <Row parcelid="002" currentlocationid="Sanjose" requestedlocationid="Michigan" deliverystatus="Delivered" requestor="Rob"/>
  </MailStatusReport> 

Несколько замечаний:

  1. Атрибут Name ColMetaData / ColList / Col во входном xml заканчивается как имя атрибута для каждого элемента Row выходного xml.
  2. Значение RowList / Row / ColList / Col во входном xml заканчивается значением атрибута в выходном xml для атрибута, который имеет тот же Pos, что и в разделе ColMetaData / ColList / Col.
  3. Атрибут ColCount ColMetaData заслуживает доверия и может быть использован в качестве счетчика при необходимости.

Псевдокод, о котором я мог подумать, будет:

 For each CurrentRow in the RowList
   Begin Building OutputRow
    For each Col in ColMetaData/ColList
      attrName = ColMetaData/ColList/Col/Name
      attrPos = ColMetaData/ColList/Col/Pos
      attrVal = CurrentRow/ColList/Col[@Pos=$attrPos]
      Add $attrName=$attrVal to the outputRow

Буду признателен за любую помощь, которую смогу получить! Спасибо Шринивас

1 Ответ

3 голосов
/ 03 января 2012

Это преобразование :

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

 <xsl:key name="kColNameByPos" match="Col/@Name"
  use="../@Pos"/>

 <xsl:template match="/*">
  <MailStatusReport>
   <xsl:apply-templates/>
  </MailStatusReport>
 </xsl:template>

 <xsl:template match="Row">
  <Row>
    <xsl:apply-templates select="*/*">
      <xsl:sort select="@Pos" data-type="number"/>
    </xsl:apply-templates>
  </Row>
 </xsl:template>

 <xsl:template match="Row/ColList/Col">
  <xsl:attribute name="{key('kColNameByPos', @Pos)}">
   <xsl:value-of select="."/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному XML-документу :

<MailStatusReport>
    <Output>
        <ColMetaData ColCount="5">
            <ColList>
                <Col  Name="parcelid" Pos="1"/>
                <Col  Name="currentlocationid" Pos="2"/>
                <Col  Name="deliverystatus" Pos="4"/>
                <Col  Name="requestedlocationid" Pos="3"/>
                <Col  Name="requestor" Pos="5"/>
            </ColList>
        </ColMetaData>
        <RowList>
            <Row>
                <ColList>
                    <Col Pos="2">Delaware</Col>
                    <Col Pos="1">001</Col>
                    <Col Pos="3">NewYork</Col>
                    <Col Pos="4">InRoute</Col>
                    <Col Pos="5">John</Col>
                </ColList>
            </Row>
            <Row>
                <ColList>
                    <Col Pos="1">002</Col>
                    <Col Pos="2">Sanjose</Col>
                    <Col Pos="3">Michigan</Col>
                    <Col Pos="4">Delivered</Col>
                    <Col Pos="5">Rob</Col>
                </ColList>
            </Row>
        </RowList>
    </Output>
</MailStatusReport>

создает искомое, правильный результат :

<MailStatusReport>
   <Row parcelid="001"
        currentlocationid="Delaware"
        requestedlocationid="NewYork"
        deliverystatus="InRoute"
        requestor="John"/>
   <Row parcelid="002"
        currentlocationid="Sanjose"
        requestedlocationid="Michigan"
        deliverystatus="Delivered"
        requestor="Rob"/>
</MailStatusReport>

Пояснение :

  1. Использование <xsl:sort> для упорядочения результатов генерации атрибутов.

  2. Использование <xsl:key> и key() функция для определения соответствия между именем столбца и положением столбца - для более удобного вычисления имени генерируемого атрибута.

  3. Создание имени атрибутовиз вычисленных значений с использованием AVT (шаблон значений атрибутов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...