根据文件内容将新节点添加到xml文件

时间:2012-04-25 09:46:05

标签: xml xslt

我需要转换我的xml文件,并根据我的xml文件的内容添加一个新节点。 例如,我有:

<sheet name="Sheet1" num="1">
<row num="3">
<cell num="1">FP1152</cell>
<cell num="2">1039_2</cell>
<cell num="3">FP000234</cell>
</row>
<row num="4">
<cell num="1">RT1152</cell>
<cell num="2">1039_1</cell>
<cell num="3">GL000235</cell>
</row>
<row num="6">
<cell num="1">FP1152</cell>
<cell num="2">1039_1</cell>
<cell num="3">FP000234</cell>
</row>

</sheet>

如果我在不同行中具有相同num atribute值但在另一对单元格中具有不同值的单元格中具有相同的值(在我的示例中,它是@ num = 3和@ num = 6的行),我想要添加这样的标志:

<sheet name="Sheet1" num="1">
<flag type="ambiguousSuplier">true<flag>
    <row num="3">
    <cell num="1">FP1152</cell>
    <cell num="2">1039_2</cell>
    <cell num="3">FP000234</cell>
    </row>
    <row num="4">
    <cell num="1">RT1152</cell>
    <cell num="2">1039_1</cell>
    <cell num="3">GL000235</cell>
    </row>
    <row num="6">
    <cell num="1">FP1152</cell>
    <cell num="2">1039_1</cell>
    <cell num="3">FP000234</cell>
    </row>

    </sheet>

1 个答案:

答案 0 :(得分:2)

如果特定工作表中的行按照 @num 为1和3的单元格进行分组,那么我认为这样做的一种方法是按键对这些单元格进行分组

<xsl:key 
 name="cells" 
 match="cell" 
 use="concat(../../@num, '|', ../cell[@num='1'], '|', ../cell[@num='3'], '|', @num)" />

这将按照其工作表编号查找单元格,并在同一行中查找单元格1和2.

然后,您需要检查工作表是否包含一个单元格,该单元格本身包含上述键中的匹配单元格但具有不同的值。这是由以下令人讨厌的陈述

完成的
<xsl:template 
  match="sheet
    [row/cell
      [text() != 
      key('cells', 
        concat(../../@num, '|', ../cell[@num='1'], '|', ../cell[@num='3'], '|', @num))/text()]]">

因此,给出以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="cells" match="cell" use="concat(../../@num, '|', ../cell[@num='1'], '|', ../cell[@num='3'], '|', @num)" />

   <xsl:template match="sheet[row/cell[text() != key('cells', concat(../../@num, '|', ../cell[@num='1'], '|', ../cell[@num='3'], '|', @num))/text()]]">
      <xsl:copy>
         <xsl:apply-templates select="@*"/>
         <flag type="ambiguousSupplier">true</flag>
         <xsl:apply-templates select="node()"/>
      </xsl:copy>
   </xsl:template>

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

当应用于您的给定XML时,输出以下内容

<sheet name="Sheet1" num="1">
   <flag type="ambiguousSupplier">true</flag>
   <row num="3">
      <cell num="1">FP1152</cell>
      <cell num="2">1039_2</cell>
      <cell num="3">FP000234</cell>
   </row>
   <row num="4">
      <cell num="1">RT1152</cell>
      <cell num="2">1039_1</cell>
      <cell num="3">GL000235</cell>
   </row>
   <row num="6">
      <cell num="1">FP1152</cell>
      <cell num="2">1039_1</cell>
      <cell num="3">FP000234</cell>
   </row>
</sheet>

我确信必须有一个更简单的解决方案,所以我不会接受这个答案,即使它确实解决了你的问题......