使用xslt将节点重命名为与其索引连接的节点名称

时间:2012-04-06 10:24:57

标签: xml xslt xls

我使用下面的xslt来转换xmls,它通过Receipt / Process迭代 节点并将类型属性添加到节点。根据节点的值,它将是string / int / float。 那部分工作正常。

我还应该将“Node”节点重命名为与其索引连接的“Node” 添加一个应该是“Name”节点值的属性。

我可能有多个“节点”,我想将其转换为这样的内容:

第一个节点到“Cuda3DLut”来自<Name>Cuda3DLut</Name>

<Node1 type="Cuda3DLut" >
<Input  type="ToolLink" role="Input" format="red,green,blue">Source</Input>
<Lut type="string">Identity</Lut>
<Output type="ToolLink" role="Output" format="red,green,blue">RESULT1</Output>
<bypass type="int">0</bypass>
<nodeRole type="string">viewing</nodeRole>
<nodeShortName type="string">LUT</nodeShortName>
</Node1>

第二个节点

<Node2 type="CudaTool" >
...
</Node2>

我还想更改“输入”节点的值,如果它是“MainMedia”到“Source”但只有那时。

非常感谢。

Source XML:

<Receipt>

  <Process>
    <Node>
      <Name>Cuda3DLut</Name>
      <Input>MainMedia</Input>
      <Lut>Identity</Lut>
      <Output>RESULT1</Output>
      <bypass>0</bypass>
      <nodeRole>viewing</nodeRole>
      <nodeShortName>LUT</nodeShortName>
    </Node>
   <Node>
      <Name>CudaTool</Name>
      <Input>MainMedia</Input>
      <Lut>Identity</Lut>
      <Output>RESULT1</Output>
      <bypass>0</bypass>
      <nodeRole>viewing</nodeRole>
      <nodeShortName>LUT</nodeShortName>
    </Node>
  </Process>

  <Encode>
    <Job>
     ...
    </Job>
  </Encode>

</Receipt>

xslt: 

<?xml version="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:template match="/">
      <cut>
        <xsl:apply-templates/>        
    </cut>
 </xsl:template>


  <xsl:template match="Process">

      <xsl:for-each select="Node/*">

        <xsl:choose>

            <xsl:when test="name() = 'Input'">

              <xsl:copy>
                <xsl:attribute name="type">ToolLink</xsl:attribute>
                <xsl:attribute name="role">Input</xsl:attribute>
                <xsl:attribute name="format">red,green,blue</xsl:attribute>
                <xsl:apply-templates select="@*|node()" />
              </xsl:copy>              

            </xsl:when>

            <xsl:when test="name() = 'Output'">
              <xsl:copy>
                <xsl:attribute name="type">ToolLink</xsl:attribute>
                <xsl:attribute name="role">Output</xsl:attribute>
                <xsl:attribute name="format">red,green,blue</xsl:attribute>
                <xsl:apply-templates select="@*|node()" />
              </xsl:copy>              

            </xsl:when>

          <xsl:otherwise>

            <!-- Add type attribute to the node based on its value -->
            <xsl:choose>
            <xsl:when test="number(.) = .">
              <xsl:choose>
                <xsl:when test="contains(., '.')">
                <xsl:copy>
                  <xsl:attribute name="type">float</xsl:attribute>
                  <xsl:apply-templates select="@*|node()" />
                </xsl:copy>
              </xsl:when>
              <xsl:otherwise>
                <xsl:copy>
                  <xsl:attribute name="type">int</xsl:attribute>
                  <xsl:apply-templates select="@*|node()" />
                </xsl:copy>
              </xsl:otherwise>
             </xsl:choose>                                      
            </xsl:when>
            <xsl:otherwise>
              <xsl:copy>
                <xsl:attribute name="type">string</xsl:attribute>
                <xsl:apply-templates select="@*|node()" />
              </xsl:copy>            
            </xsl:otherwise>            
          </xsl:choose>

        </xsl:otherwise>            
        </xsl:choose>

      </xsl:for-each>

  </xsl:template>

  <xsl:template match="Encode">    
  </xsl:template>

</xsl:stylesheet>

2 个答案:

答案 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:template match="Node">
     <xsl:element name="Node{position()}">
       <xsl:attribute name="type">
         <xsl:value-of select="Name"/>
       </xsl:attribute>
       <xsl:apply-templates select="*[not(self::Name)]"/>
     </xsl:element>
 </xsl:template>

 <xsl:template match="Node/*" priority="-1">
  <xsl:copy>
    <xsl:attribute name="type">string</xsl:attribute>
    <xsl:value-of select="."/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="Node/Input">
   <Input  type="ToolLink" role="Input" format="red,green,blue">Source</Input>
 </xsl:template>

 <xsl:template match="Output">
   <Output  type="ToolLink" role="Output" format="red,green,blue">
     <xsl:value-of select="."/>
   </Output>
 </xsl:template>

 <xsl:template match="bypass">
  <bypass type="int"><xsl:value-of select="."/></bypass>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<Receipt>
    <Process>
        <Node>
            <Name>Cuda3DLut</Name>
            <Input>MainMedia</Input>
            <Lut>Identity</Lut>
            <Output>RESULT1</Output>
            <bypass>0</bypass>
            <nodeRole>viewing</nodeRole>
            <nodeShortName>LUT</nodeShortName>
        </Node>
        <Node>
            <Name>CudaTool</Name>
            <Input>MainMedia</Input>
            <Lut>Identity</Lut>
            <Output>RESULT1</Output>
            <bypass>0</bypass>
            <nodeRole>viewing</nodeRole>
            <nodeShortName>LUT</nodeShortName>
        </Node>
    </Process>
    <Encode>
        <Job>      ...     </Job>
    </Encode>
</Receipt>

会产生想要的正确结果:

<Node1 type="Cuda3DLut">
   <Input type="ToolLink" role="Input" format="red,green,blue">Source</Input>
   <Lut type="string">Identity</Lut>
   <Output type="ToolLink" role="Output" format="red,green,blue">RESULT1</Output>
   <bypass type="int">0</bypass>
   <nodeRole type="string">viewing</nodeRole>
   <nodeShortName type="string">LUT</nodeShortName>
</Node1>
<Node2 type="CudaTool">
   <Input type="ToolLink" role="Input" format="red,green,blue">Source</Input>
   <Lut type="string">Identity</Lut>
   <Output type="ToolLink" role="Output" format="red,green,blue">RESULT1</Output>
   <bypass type="int">0</bypass>
   <nodeRole type="string">viewing</nodeRole>
   <nodeShortName type="string">LUT</nodeShortName>
</Node2> 

答案 1 :(得分:0)

我认为您可以使用<xsl:element/>position()功能生成您的节点。

<xsl:template match="Receipt/Process/Node">
    <xsl:variable name="nodename">
        <xsl:text>Node</xsl:text>
        <xsl:value-of select="position()"/>
    </xsl:variable>
    <xsl:element name="{$nodename}">
        ...
    </xsl:element>
</xsl:template>