元素包含值时的XSL转换

时间:2014-10-09 20:59:59

标签: xml xslt

我在.xml上做了一些xsl转换,我设法做了一些我想做的事,但我无法弄清楚剩下的。这是.xml内容

  <Parent1>
    <Parent2>
        <Number>"100"</Number>
        <Name>"SanJose"</Name>
        <Type>"SanJoseExtra"</Type>
        <Adress>Avenue 54</Adress>
        <Status>2</Status>
        <TR5>1</TR5>
        <TR10>0</TR10>
        <Modifier>0</Modifier>
    </Parent2>
    <Parent2>
        <Number>"100"</Number>
        <Name>"SanTropez"</Name>
        <Type>"SanTropezSmall"</Type>
        <Adress>British Cal 3</Adress>
        <Status>2</Status>
        <TR5>1</TR5>
        <TR10>1</TR10>
        <Modifier>0</Modifier>
    </Parent2>
    <Parent2>
        <Number>"101"</Number>
        <Name>"SanJose"</Name>
        <Type>"SanDiegoMedium"</Type>
        <Adress>French Revolution n.n.</Adress>
        <Status>2</Status>
        <TR5>1</TR5>
        <TR10>1</TR10>
        <Modifier>0</Modifier>
    </Parent2>
    <Parent2>
        <Number>"100"</Number>
        <Name>"SanJose"</Name>
        <Type>"SanJoseSmall"</Type>
        <Adress>Avenue 54</Adress>
        <Status>1</Status>
        <TR5>1</TR5>
        <TR10>0</TR10>
        <Modifier>0</Modifier>
    </Parent2>
</Parent1>

如果<Name>包含SanJose并且<Status>包含1,我想将Modifier值更改为1.所以我做了类似这样的输出:

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



    <xsl:template match="XMLLine[contains(./Name,'SanJose') and contains(./Status,'1')]"> 
        <Parent2>
                        <xsl:copy-of select="Number" />
                        <xsl:copy-of select="Name" />
                        <xsl:copy-of select="Type" />
                        <xsl:copy-of select="Adress" />
                        <xsl:copy-of select="Status" />
                        <xsl:copy-of select="TR5" />
                        <xsl:copy-of select="TR10" />
                        <Modifier>1</Modifier>
        </Parent2> 
        </xsl:template>
    </xsl:stylesheet>

但后来我意识到SanJose的状态为1,我也想将修改器更改为1,但是除了我提前知道的名字和我不知道的100之外,我没有任何连接它的东西。因为列表还在继续,所以要提前知道。

总而言之,我发现的问题是我有可以使用的通用名称和状态,但我也想将它应用于包含名称SanJose但具有相同编号的其他节点,我可以&#t; t提前知道。

修改 为每个具有相同Number的事件添加增量。因此,不是将修改器更改为1,而是尝试将其设置为STATUS1,STATUS2,STATUS3 ....等等。我尝试修改你的xsl:

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

<xsl:variable name="incre">0</xsl:variable>

<xsl:key name="matching-parent" match="Parent2[Name='SanJose' and Status=1]" use="Number" />

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

<xsl:template match="Modifier[key('matching-parent', ../Number)]/text()"> 
<xsl:value-of select="concat('STATUS', $incre+1)" /> 
</xsl:template> 

</xsl:stylesheet>

但是,我使用$ increment的逻辑失败,因为它从不递增,它始终保持STATUS1。

2 个答案:

答案 0 :(得分:1)

我根据您的问题了解了以下样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:strip-space elements="*"/>

    <xsl:output indent="yes" omit-xml-declaration="yes"/>

    <xsl:key name="SJ" match="Parent2[contains(Name, 'SanJose') and Status = 1]" use="Number"/>

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

    <xsl:template match="Modifier">
        <xsl:copy>
            <xsl:choose>
                <xsl:when test="contains(preceding-sibling::Name, 'SanJose') 
                                and
                                preceding-sibling::Status = 1">
                    <xsl:text>1</xsl:text>
                </xsl:when>
                <xsl:when test="key('SJ', preceding-sibling::Number)">
                    <xsl:text>1</xsl:text>
                </xsl:when>
                <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

它产生:

<Parent1>
   <Parent2>
      <Number>"100"</Number>
      <Name>"SanJose"</Name>
      <Type>"SanJoseExtra"</Type>
      <Adress>Avenue 54</Adress>
      <Status>2</Status>
      <TR5>1</TR5>
      <TR10>0</TR10>
      <Modifier>1</Modifier>
   </Parent2>
   <Parent2>
      <Number>"100"</Number>
      <Name>"SanTropez"</Name>
      <Type>"SanTropezSmall"</Type>
      <Adress>British Cal 3</Adress>
      <Status>2</Status>
      <TR5>1</TR5>
      <TR10>1</TR10>
      <Modifier>1</Modifier>
   </Parent2>
   <Parent2>
      <Number>"101"</Number>
      <Name>"SanJose"</Name>
      <Type>"SanDiegoMedium"</Type>
      <Adress>French Revolution n.n.</Adress>
      <Status>2</Status>
      <TR5>1</TR5>
      <TR10>1</TR10>
      <Modifier>0</Modifier>
   </Parent2>
   <Parent2>
      <Number>"100"</Number>
      <Name>"SanJose"</Name>
      <Type>"SanJoseSmall"</Type>
      <Adress>Avenue 54</Adress>
      <Status>1</Status>
      <TR5>1</TR5>
      <TR10>0</TR10>
      <Modifier>1</Modifier>
   </Parent2>
</Parent1>

答案 1 :(得分:1)

  

首先更改<name> = SanJose和<status> = 1的所有节点,   然后从这些案例中取出<Number>并在任何地方进行更改   发生<Number>的其他地方

如果我理解正确,这也可以表示为:

  1. Number;
  2. 对所有节点进行分组
  3. 如果某个组的任何成员满足[Name='SanJose' and Status='1'],则更改整个组。
  4. 通过这种方式来看,您可以将解决方案简化为:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:key name="matching-parent" match="Parent2[Name='SanJose' and Status=1]" use="Number" />
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Modifier[key('matching-parent', ../Number)]/text()">
        <xsl:value-of select="1"/>
    </xsl:template>
    
    </xsl:stylesheet>
    

    应用于以下测试输入

    <Parent1>
        <Parent2>
            <Number>111</Number>
            <Name>Starter</Name>
            <Status>2</Status>
            <Modifier>0</Modifier>
        </Parent2>
        <Parent2>
            <Number>111</Number>
            <Name>SanJose</Name>
            <Status>1</Status>
            <Modifier>0</Modifier>
        </Parent2>
        <Parent2>
            <Number>222</Number>
            <Name>SanJose</Name>
            <Status>2</Status>
            <Modifier>0</Modifier>
        </Parent2>
        <Parent2>
            <Number>111</Number>
            <Name>Another 1</Name>
            <Status>2</Status>
            <Modifier>0</Modifier>
        </Parent2>
        <Parent2>
            <Number>222</Number>
            <Name>Another 2</Name>
            <Status>1</Status>
            <Modifier>0</Modifier>
        </Parent2>
        <Parent2>
            <Number>111</Number>
            <Name>SanJose</Name>
            <Status>2</Status>
            <Modifier>0</Modifier>
        </Parent2>
    </Parent1>
    

    产生结果

    <?xml version="1.0" encoding="UTF-8"?>
    <Parent1>
       <Parent2>
          <Number>111</Number>
          <Name>Starter</Name>
          <Status>2</Status>
          <Modifier>1</Modifier>
       </Parent2>
       <Parent2>
          <Number>111</Number>
          <Name>SanJose</Name>
          <Status>1</Status>
          <Modifier>1</Modifier>
       </Parent2>
       <Parent2>
          <Number>222</Number>
          <Name>SanJose</Name>
          <Status>2</Status>
          <Modifier>0</Modifier>
       </Parent2>
       <Parent2>
          <Number>111</Number>
          <Name>Another 1</Name>
          <Status>2</Status>
          <Modifier>1</Modifier>
       </Parent2>
       <Parent2>
          <Number>222</Number>
          <Name>Another 2</Name>
          <Status>1</Status>
          <Modifier>0</Modifier>
       </Parent2>
       <Parent2>
          <Number>111</Number>
          <Name>SanJose</Name>
          <Status>2</Status>
          <Modifier>1</Modifier>
       </Parent2>
    </Parent1>
    

    请特别注意示例中的最后一个节点。


    编辑:

    如果我理解你的新要求,你需要改变这个:

    <xsl:template match="Modifier[key('matching-parent', ../Number)]/text()">
        <xsl:value-of select="1"/>
    </xsl:template>
    

    到:

    <xsl:template match="Modifier[key('matching-parent', ../Number)]">
        <xsl:copy>
            <xsl:value-of select="concat('STATUS', count(../preceding-sibling::Parent2[key('matching-parent', Number)]) + 1)"/>
        </xsl:copy>
    </xsl:template>