【问题标题】:XML to XML Transform using XSL使用 XSL 将 XML 转换为 XML
【发布时间】:2012-02-01 04:37:47
【问题描述】:

我需要将 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. 输入 xml 中 ColMetaData/ColList/Col 的 Name 属性最终作为输出 xml 的每个 Row 元素的属性名称。
  2. 输入 xml 中的 RowList/Row/ColList/Col 的值最终成为输出 xml 中与 ColMetaData/ColList/Col 部分中具有相同 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

如果能得到任何帮助,我将不胜感激! 谢谢 斯里尼瓦斯

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    这种转变

    <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. 使用 &lt;xsl:sort&gt; 对属性生成的结果进行排序。

    2. 使用 &lt;xsl:key&gt;key() 函数定义列名和列位置之间的映射——为了更方便计算正在生成的属性。

    3. 使用 AVT(属性值模板)从计算值生成属性名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-22
      • 2022-01-07
      • 1970-01-01
      • 2014-07-30
      • 1970-01-01
      • 2016-02-13
      • 1970-01-01
      • 2012-08-12
      相关资源
      最近更新 更多