将数据从兄弟节点获取到节点,其中数据等于其他节点的数据

时间:2012-11-20 22:08:29

标签: xml variables xslt merge matching

我正在一个XSLT文档中处理两个XML文档,并尝试合并要放入一个HTML文档的数据。

文件匹配一个点,即id。 id将作为 foo1.xml 中car节点的属性被找到。关于 foo2.xml ,可以在Data节点内找到id,它是第一个Cell节点(Row节点的子节点)的子节点。第一个Cell节点后面的Cell节点包含Data节点,其中包含所需的数据(颜色和条件)。

当在XSLT文档中将数据添加到td单元格时,我(在某种程度上)需要在 foo2.xml 中找到正确的id,并将其放入汽车的颜色和条件中最后两个td。

在下面的XSLT文档中,您可以看到我尝试执行此操作失败。那么,怎么做呢?

提前多多感谢!

注意:两个文件中id的顺序不一样。

foo1.xml:

<cars>
  <car id="8">
    <brand>Saab</brand>
    <model>95</model>
    <year>2011</year>
  </car>
  <car id="57">
    <brand>Chrysler</brand>
    <model>Voyager</model>
    <year>2010</year>
  </cars>
  ...

foo2.xml:

<Table ss:ExpandedColumnCount="5" ss:ExpandedRowCount="79" x:FullColumns="1"
   x:FullRows="1" ss:DefaultColumnWidth="65" ss:DefaultRowHeight="15">
   <Column ss:Index="2" ss:AutoFitWidth="0" ss:Width="43"/>
   <Column ss:AutoFitWidth="0" ss:Width="113"/>
   <Column ss:Index="5" ss:AutoFitWidth="0" ss:Width="220"/>
   <Row ss:Index="6">
    <Cell ss:Index="3" ss:StyleID="s62"/>
   </Row>
   <Row>
    <Cell ss:Index="3" ss:StyleID="s62"/>
   </Row>
   <Row>
    <Cell ss:Index="3" ss:StyleID="s62"/>
   </Row>
   <Row>
    <Cell ss:Index="2"><Data ss:Type="String">57</Data></Cell>    // <-- where the id is to be found
    <Cell ss:StyleID="s62"><Data ss:Type="String">Yellow</Data></Cell>
    <Cell><Data ss:Type="String">New</Data></Cell>
   </Row>
   <Row>
    <Cell ss:Index="2"><Data ss:Type="Number">8</Data></Cell>    // <-- where the id is to be found
    <Cell ss:StyleID="s62"><Data ss:Type="Number">Black</Data></Cell>
    <Cell><Data ss:Type="Number">Used</Data></Cell>
   </Row>
   <Row>
    <Cell ss:Index="2"><Data ss:Type="Number">25</Data></Cell>    // <-- where the id is to be found
    <Cell ss:StyleID="s62"><Data ss:Type="Number">Blue</Data></Cell>
    <Cell><Data ss:Type="Number">Used</Data></Cell>
   </Row>
   ...

merge.xsl:

   <- declarations... ->
         xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" >   <-- the XML namespace (ss:)

    <xsl:variable name="foo2" select="document('foo2.xml')" />

    <xsl:template match="/">
        <html>
            <head>
                <title>Cars</title>
            </head>
        <body>
            <xsl:apply-templates select="cars" />
        </body>  
        </html>
    </xsl:template>

    <xsl:template match="cars">

    <xsl:for-each select="$foo2//ss:Row">
        <xsl:value-of select="ss:Cell/ss:Data/text()" />
    </xsl:for-each>

    <table>
        <tr>
            <th>Id</th> <th>Brand</th> <th>Model</th> <th>Year</th> <th>Color</th> <th>Condition</th>
        </tr>
        <xsl:apply-templates select="car" />
    </table>
    </xsl:template>

    <xsl:template match="car">
        <xsl:variable name="id" select="data[2]/text()" />
            <tr>
                <td><xsl:value-of select="@id" /></td>
                <td><xsl:value-of select="brand" /></td>
                <td><xsl:value-of select="model" /></td>
                <td><xsl:value-of select="year" /></td>

                <td><xsl:value-of select="$positions//ss:Row/ss:Cell/ss:Data=@id/preceding-sibling::ss:Cell" /></td> <-- failed try (color)
                <td> ??? (Condition) </td>
            </tr>
    </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分: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="kRowById" match="Row" use="Cell[1]/Data"/>

 <xsl:variable name="vDoc2" select="document('file:///c:/temp/delete/foo2.xml')"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="car">
  <xsl:variable name="vId" select="@id"/>
  <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     <xsl:for-each select="$vDoc2">
       <color><xsl:value-of select="key('kRowById', $vId)/Cell[2]/Data"/></color>
       <condition><xsl:value-of select="key('kRowById', $vId)/Cell[3]/Data"/></condition>
     </xsl:for-each>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

应用于提供的foo1.xml文档

<cars>
    <car id="8">
        <brand>Saab</brand>
        <model>95</model>
        <year>2011</year>
    </car>
    <car id="57">
        <brand>Chrysler</brand>
        <model>Voyager</model>
        <year>2010</year>
    </car>
</cars>

并且提供的foo2.xml文档位于:c:\temp\delete

    <Table xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
       xmlns:x="some:x"
       ss:ExpandedColumnCount="5" ss:ExpandedRowCount="79" x:FullColumns="1"
       x:FullRows="1" ss:DefaultColumnWidth="65" ss:DefaultRowHeight="15">
       <Column ss:Index="2" ss:AutoFitWidth="0" ss:Width="43"/>
       <Column ss:AutoFitWidth="0" ss:Width="113"/>
       <Column ss:Index="5" ss:AutoFitWidth="0" ss:Width="220"/>
       <Row ss:Index="6">
        <Cell ss:Index="3" ss:StyleID="s62"/>
       </Row>
       <Row>
        <Cell ss:Index="3" ss:StyleID="s62"/>
       </Row>
       <Row>
        <Cell ss:Index="3" ss:StyleID="s62"/>
       </Row>
       <Row>
        <Cell ss:Index="2"><Data ss:Type="String">57</Data></Cell>    // -- where the id is to be found
        <Cell ss:StyleID="s62"><Data ss:Type="String">Yellow</Data></Cell>
        <Cell><Data ss:Type="String">New</Data></Cell>
       </Row>
       <Row>
        <Cell ss:Index="2"><Data ss:Type="Number">8</Data></Cell>    // -- where the id is to be found
        <Cell ss:StyleID="s62"><Data ss:Type="Number">Black</Data></Cell>
        <Cell><Data ss:Type="Number">Used</Data></Cell>
       </Row>
       <Row>
        <Cell ss:Index="2"><Data ss:Type="Number">25</Data></Cell>    // -- where the id is to be found
        <Cell ss:StyleID="s62"><Data ss:Type="Number">Blue</Data></Cell>
        <Cell><Data ss:Type="Number">Used</Data></Cell>
       </Row>
</Table>

生成所需的正确合并输出

<cars>
   <car id="8">
      <brand>Saab</brand>
      <model>95</model>
      <year>2011</year>
      <color>Black</color>
      <condition>Used</condition>
   </car>
   <car id="57">
      <brand>Chrysler</brand>
      <model>Voyager</model>
      <year>2010</year>
      <color>Yellow</color>
      <condition>New</condition>
   </car>
</cars>

<强>解释

正确使用:

  1. document() 功能。

  2. <强> Keys

  3. 更改当前文档的 <xsl:for-each> 指令。在XSLT 1.0中, key() 函数在当前文档上运行。