以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 XSL/XSLT/XSL-FO/CSS 』  (http://bbs.xml.org.cn/list.asp?boardid=8)
----  关于给xml元素序列号的问题  (http://bbs.xml.org.cn/dispbbs.asp?boardid=8&rootid=&id=14631)


--  作者:lifangde125
--  发布时间:2/20/2005 7:09:00 AM

--  关于给xml元素序列号的问题
XML文件:A.xml
<?xml version="1.0" encoding="utf-8"?>
<?xml:stylesheet type="text/xsl" href="A.xsl"?>
<statemachine>
  <开始状态 ID="eee_0001" name="1111"/>
  <状态 ID="eee_0002" name="2222"/>
  <状态 ID="eee_0003" name="3333"/>
  <结束状态 ID="eee_0004" name="4444"/>
  <连接 ID="eee_0005" name="5555"/>
  <连接 ID="eee_0006" name="6666"/>
  <连接 ID="eee_0007" name="7777"/>
</statemachine>
<statemachine>
  <开始状态 ID="eee_0008" name="8888"/>
  <状态 ID="eee_0009" name="0000"/>
  <结束状态 ID="eee_0010" name="1234"/>
  <连接 ID="eee_0011" name="5678"/>
  <连接 ID="eee_0012" name="9999"/>
</statemachine>

XSL文件:A.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:for-each select="statemachine">
   <SFC>
     <xsl:for-each select="开始状态">
       <step>
         <xsl:attribute name="localID">
           <xsl:value-of select="ID">
         </xsl:attribute>
       </step>
     </xsl:for-each>
     <xsl:for-each select="状态">
       <step>
         <xsl:attribute name="localID">
           <xsl:value-of select="ID">
         </xsl:attribute>
       </step>
     </xsl:for-each>
     <xsl:for-each select="结束状态">
       <step>
         <xsl:attribute name="localID">
           <xsl:value-of select="ID">
         </xsl:attribute>
       </step>
     </xsl:for-each>
     <xsl:for-each select="连接">
       <transition>
         <xsl:attribute name="localID">
           <xsl:value-of select="ID">
         </xsl:attribute>
       </transition>
     </xsl:for-each>
   </SFC>
</xsl:for-each>

这样我得到"localID"都是xml中给的string形式的,但是我的schema中要求"localID"为int,而且,状态和连接要顺序输出并且给出从0开始的数作为"localID"
理想的结果是这样的
<SFC>
  <开始状态 ID="0"/>
  <连接 ID="1"/>
  <状态 ID="2"/>
  <连接 ID="3"/>
  <状态 ID="4"/>
  <连接 ID="5"/>
  <结束状态 ID="6"/>
</SFC>
<SFC>
  <开始状态 ID="0"/>
  <连接 ID="1"/>
  <状态 ID="2"/>
  <连接 ID="3"/>
  <结束状态 ID="4"/>
</SFC>

上面的也只是个例子,我的xml是从一个UML Tools 生成的,所以对每个statemachine不知道会有多少个"状态"或"连接".
在xslt中是不是有什么函数可以解决这种问题呢?


--  作者:sam
--  发布时间:2/24/2005 10:40:00 PM

--  
代码写的比较丑陋,不知道是不是那个意思
xml
<?xml version="1.0" encoding="UTF-8"?>
<Package>
 <statemachine>
  <start ID="eee_0001" name="1111"/>
  <status ID="eee_0002" name="2222"/>
  <status ID="eee_0003" name="3333"/>
  <end ID="eee_0004" name="4444"/>
  <connect ID="eee_0005" name="5555"/>
  <connect ID="eee_0006" name="6666"/>
  <connect ID="eee_0007" name="7777"/>
 </statemachine>
 <statemachine>
  <start ID="eee_0008" name="8888"/>
  <status ID="eee_0009" name="0000"/>
  <end ID="eee_0010" name="1234"/>
  <connect ID="eee_0011" name="5678"/>
  <connect ID="eee_0012" name="9999"/>
 </statemachine>
</Package>

xsl
<?xml version="1.0" encoding="UTF-8"?>
<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="/">
  <xsl:for-each select="//statemachine">
  <SFC>
   <start>
    <xsl:attribute name="LocalID"><xsl:value-of select="0"/></xsl:attribute>
    <xsl:attribute name="ID"><xsl:value-of select="start/@ID"/></xsl:attribute>
   </start>
   <xsl:call-template name="for-loop">
    <xsl:with-param name="testValue" select="count(*)"/>
   </xsl:call-template>
   <end>
    <xsl:attribute name="LocalID"><xsl:value-of select="count(*)-1"/></xsl:attribute>
    <xsl:attribute name="ID"><xsl:value-of select="end/@ID"/></xsl:attribute>
   </end>
   </SFC>
  </xsl:for-each>
 </xsl:template>
 <xsl:template name="for-loop">
  <xsl:param name="i" select="1"/>
  <xsl:param name="j" select="1"/>
  <xsl:param name="testValue" select="1"/>
  <xsl:choose>
   <xsl:when test="$i &lt;= $testValue">
    <xsl:for-each select="connect[$i]">
     <connect>
      <xsl:attribute name="LocalID"><xsl:value-of select="$j"/></xsl:attribute>
      <xsl:attribute name="ID"><xsl:value-of select="@ID"/></xsl:attribute>
     </connect>
    </xsl:for-each>
    <xsl:for-each select="status[$i]">
     <status>
      <xsl:attribute name="LocalID"><xsl:value-of select="$j+1"/></xsl:attribute>
      <xsl:attribute name="ID"><xsl:value-of select="@ID"/></xsl:attribute>
     </status>
    </xsl:for-each>
    <xsl:call-template name="for-loop">
     <xsl:with-param name="i" select="$i + 1"/>
     <xsl:with-param name="j" select="$j+2"/>
     <xsl:with-param name="testValue" select="$testValue"/>
    </xsl:call-template>
   </xsl:when>
   <xsl:otherwise>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>


--  作者:lifangde125
--  发布时间:2/25/2005 9:52:00 PM

--  
sam,太好了,非常感谢,就是我想要的.
还想问问你,如果我的理想输出是如下的:

<SFC>
  <开始状态 ID="0"/>
  <状态 ID="1" refID="3"/>
  <状态 ID="2" refID="4"/>
  <连接 ID="3" refID="0"/>
  <连接 ID="4" refID="1"/>
  <连接 ID="5" refID="2"/>
  <结束状态 ID="6" refID="5"/>
</SFC>
多了一个refID, 它表示这个元素和谁连接,而且<连接>和<状态>不用象上面那样颠倒顺序,用你上面的方法可以吗?


--  作者:lifangde125
--  发布时间:2/26/2005 11:41:00 PM

--  sam,在你的程序里可以用,我的就不行
我的xslt有点复杂, 我把它简化了一下:
<?xml version='1.0' ?>
<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://www.plcopen.org/xml/tc6.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.plcopen.org/xml/tc6.xsd .\TC6_XML_V099.xsd">
  <xsl:template match="/">
    <project>
      <types>
        <pous>
           <xsl:for-each select="XMI/XMI.content/Class">
 <pou>
   <xsl:attribute name="pouType">program</xsl:attribute>
     <SFC>
        <xsl:for-each select="../statemachine/Behavioral_Elements.State_Machines.开始状态">
        <step>
          <xsl:attribute name="localId">
            <xsl:value-of select="0"/></xsl:attribute>
          <xsl:attribute name="name">start</xsl:attribute>
        </step>
                     </xsl:for-each>
                     <xsl:call-template name="for-loop">
             <xsl:with-param name="testvalue" select="count(*)"/>
                     </xsl:call-template>
                     <xsl:for-each select="../statemachine/Behavioral_Elements.State_Machines.结束状态>             <jumpstep>
          <xsl:attribute name="localId">
             <xsl:value-of select="count(*)-1"/></xsl:attribute>
       </jumpstep>
                  </xsl:for-each>
              </SFC>
         </pou>
       </xsl:for-each>
     </pous>
    <types>
  </project>
</xsl:template>
<xsl:template name="for-loop">
  <xsl:param name="i" select="1"/>
  <xsl:param name="j" select="1"/>
  <xsl:param name="testvalue" select="1"/>
  <xsl:if test="$i &lt;= $testvalue">
 <xsl:for-each select="Behavioral_Elements.State_Machines.CompositeState[$i]"><!--中间状态, 与开始状态和结束状态在一个节点下-->
   <step>
      <xsl:attribute name="localId">
        <xsl:value-of select="$j"/></xsl:attribute>
 </step>
             </xsl:for-each>
             <xsl:for-each select="Behavioral_Elements.State_Machines.Transition[$i]">
             <!--连接,与状态在同一节点下>
 <transition>
 <xsl:attribute name="localId">
 <xsl:value-of select="$j+2"/></xsl:attribute>
 </transition>
           </xsl:for-each>
          <xsl:call-template name="for-loop">
 <xsl:with-param name="i" select="$i+1"/>
 <xsl:with-param name="j" select="$j+2"/>
 <xsl:with-param name="testvalue" select="$testvalue"/>
          </xsl:call-template>
      </xsl:template>
</xsl:stylesheet>

在我的quelle.xml中,
XMI/XMI.content/Class|statemachine,class 和statemachine是同一级, 我要将class定义成pou,然后再将statemachine中的不同状态和连接定义成<step><jumpstep>和<transition>, 我照你的方法写的,但是还是不对. 如果可以,我只需要状态和连接顺序输出,不用颠倒,而且加上refID.
sam, 你有没有办法?


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
82.031ms