以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 XSL/XSLT/XSL-FO/CSS 』  (http://bbs.xml.org.cn/list.asp?boardid=8)
----  请教:用xslt如何只替换xml文件中的属性值,其他原样输出成xml  (http://bbs.xml.org.cn/dispbbs.asp?boardid=8&rootid=&id=9237)


--  作者:mature_shadow
--  发布时间:8/9/2004 6:04:00 PM

--  请教:用xslt如何只替换xml文件中的属性值,其他原样输出成xml
xml文件:
<employees>
  <employee>
    <id value="e0001"/>
    <name>stone</name>
  </employee>
  <employee>
    <id value="e0002"/>
    <name>alison</name>
  </employee>
</employees>

想要通过使用xslt转换得到如下结果(id属性值变了):
注:因为元xml比较大,我不想在xslt文件中硬写元素名,就是想要通过使用xslt语法,嗯,比如自动写上元素名(值)/属性名(值)什么的
<employees>
  <employee>
    <id value="EMP1"/>
    <name>stone</name>
  </employee>
  <employee>
    <id value="EMP2"/>
    <name>alison</name>
  </employee>
</employees>


--  作者:kittypig
--  发布时间:8/12/2004 3:33:00 PM

--  
<?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" encoding="UTF-8" indent="yes"/>

<xsl:template match="employees">
  <xsl:element name="employees">
   <xsl:apply-templates select="employee"/>
  </xsl:element>
 </xsl:template>
 <xsl:template match="employee">
  <xsl:element name="employee">
   <xsl:for-each select="*">
    <xsl:if test="name() = 'id'">
        <xsl:element name="id">
         <xsl:attribute name="value">
      <xsl:if test="@value = 'e0001'">
      EMP1
      </xsl:if>
      <xsl:if test="@value = 'e0002'">
      EMP2
      </xsl:if>
      </xsl:attribute>
     </xsl:element>
    </xsl:if>
    <xsl:if test="name() != 'id'">
        <xsl:element name="{name()}">
      <xsl:value-of select="."/>
     </xsl:element>
    </xsl:if>
   </xsl:for-each>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>


--  作者:kittypig
--  发布时间:8/12/2004 3:34:00 PM

--  
我转化的方法很笨啊,不过能用就是了
--  作者:jun
--  发布时间:8/12/2004 5:34:00 PM

--  
若能访问父结点的 position(),我这招也是不错的
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:output method="xml" indent="yes"/>
 <xsl:template match="/">
  <xsl:apply-templates/>
 </xsl:template>
 <xsl:template match="node()|@*">
  <xsl:choose>
   <xsl:when test="./@value">
    <xsl:element name="id">
     <xsl:attribute name="value"><xsl:value-of select="concat('EMP',position())"/></xsl:attribute>
    </xsl:element>
   </xsl:when>
   <xsl:otherwise>
    <xsl:copy>
     <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

--  作者:kittypig
--  发布时间:8/12/2004 6:02:00 PM

--  
我觉得xslt其实很有意思,你运用的好,就可以用很简洁的方法把xml转换了,感觉像在设计算法,楼上的方法就很简洁啊,看着很舒服,不过我没有看过position(),也没怎么看xpath,所以我只能很笨的进行转换了。不过很奇怪,为什么我试了下,两个id的alue都被转换为EMP1了呢,第2个的alue应该是EMP2啊,你用这个concat('EMP',position()),应该是要把EMP加到前面啊,可是他最后一位的编号怎么保留的啊
--  作者:jun
--  发布时间:8/13/2004 10:23:00 AM

--  
是的,这个position()我没用好,应该是父结点的position(),可惜我还用不来
若有谁知道能否贴出来
--  作者:jun
--  发布时间:8/13/2004 3:28:00 PM

--  
这样不错吧
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:output method="xml" indent="yes"/>
 <xsl:template match="/">
  <xsl:apply-templates/>
 </xsl:template>
 <xsl:template match="node()|@*">
  <xsl:choose>
   <xsl:when test="./@value">
    <xsl:element name="id">
     <xsl:attribute name="value"><xsl:value-of select="concat('EMP',substring(./@value,5,1))"/></xsl:attribute>
    </xsl:element>
   </xsl:when>
   <xsl:otherwise>
    <xsl:copy>
     <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

--  作者:bluecoffee
--  发布时间:8/20/2004 11:18:00 AM

--  
楼上的方法就很好啊, 我学到了不少的东西. 但有一个bug.
问题如果这样<id value="e0001" value2 ="1" />,value="e0001" 就显示不出来了
为了让它更好 我修改了一下
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
 <xsl:template match="/">
  <xsl:apply-templates/>
 </xsl:template>
 <xsl:template match="node()|@*">
  <xsl:choose>
   <xsl:when test="name() =  'value' ">
     <xsl:attribute name="value"><xsl:value-of select="concat('EMP',substring(../@value,5,1))"/></xsl:attribute>
   </xsl:when>
   <xsl:otherwise>
    <xsl:copy>
     <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

能加上父节点的名字=id的判断,就更好了, 可惜我不会


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