2012-01-03 102 views
2

我需要将xml数据转换为其他格式。我做了很少XSL的东西,我的互联网搜索没有给我需要的结果。我有这个样本XML:使用XSL将XML转换为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. ColMetaData/ColList /列的输入XML的名称属性最终成为输出xml的每个Row元素的属性名称。
  2. RowList/Row/ColList/Col在输入xml中的值最终成为输出xml中属性的值,该属性与ColMetaData/ColList/Col部分中的Pos具有相同的Pos。
  3. ColMetaData的ColCount属性值得信任,如果需要可以用作计数器。

的伪代码,我能想到的是:

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 

我希望得到任何帮助,我能搞定! 感谢 SRINIVAS

回答

3

这种转变

<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(属性值模板)生成计算值的属性名称。

+0

非常感谢你Dimitre这按预期工作。 – 2012-01-03 17:13:42

+0

@SrinivasPalakala:不客气。 – 2012-01-03 17:23:16