我这里有一个xml文件..
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE dependencies SYSTEM "http://depfind.sourceforge.net/dtd/dependencies.dtd">
<dependencies>
<package confirmed="yes">
<name>com.infopro.Dependency</name>
<class confirmed="yes">
<name>com.infopro.Dependency.A</name>
<outbound type="class" confirmed="no">java.lang.Object</outbound>
<outbound type="class" confirmed="no">javax.ejb.Stateless</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.a</inbound>
<feature confirmed="yes">
<name>com.infopro.Dependency.A.A()</name>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.A.b</outbound>
<outbound type="class" confirmed="yes">com.infopro.Dependency.B</outbound>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</outbound>
<outbound type="feature" confirmed="no">java.lang.Object.Object()</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.A.b</name>
<outbound type="class" confirmed="yes">com.infopro.Dependency.B</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.A.check(java.lang.String, java.lang.String)</name>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.A.stat</outbound>
<outbound type="class" confirmed="no">java.lang.String</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.doStatus()</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.A.doStatus()</name>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.A.check(java.lang.String, java.lang.String)</outbound>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.A.name</outbound>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.A.user_id</outbound>
<outbound type="class" confirmed="no">java.lang.String</outbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.A.name</name>
<outbound type="class" confirmed="no">java.lang.String</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.doStatus()</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.A.stat</name>
<outbound type="class" confirmed="no">java.lang.String</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.check(java.lang.String, java.lang.String)</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.A.user_id</name>
<outbound type="class" confirmed="no">java.lang.String</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.doStatus()</inbound>
</feature>
</class>
<class confirmed="yes">
<name>com.infopro.Dependency.B</name>
<outbound type="class" confirmed="yes">com.infopro.Dependency.C</outbound>
<outbound type="class" confirmed="no">java.lang.Object</outbound>
<outbound type="class" confirmed="no">javax.ejb.Stateless</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.b</inbound>
<feature confirmed="yes">
<name>com.infopro.Dependency.B.B()</name>
<outbound type="class" confirmed="yes">com.infopro.Dependency.A</outbound>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</outbound>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.B.a</outbound>
<outbound type="feature" confirmed="no">java.lang.Object.Object()</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.B.a</name>
<outbound type="class" confirmed="yes">com.infopro.Dependency.A</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.B.check(java.lang.String, java.lang.String)</name>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.B.stat</outbound>
<outbound type="class" confirmed="no">java.lang.String</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.doStatus()</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.B.doStatus()</name>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.B.check(java.lang.String, java.lang.String)</outbound>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.B.name</outbound>
<outbound type="feature" confirmed="yes">com.infopro.Dependency.B.user_id</outbound>
<outbound type="class" confirmed="no">java.lang.String</outbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.B.name</name>
<outbound type="class" confirmed="no">java.lang.String</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.doStatus()</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.B.stat</name>
<outbound type="class" confirmed="no">java.lang.String</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.check(java.lang.String, java.lang.String)</inbound>
</feature>
<feature confirmed="yes">
<name>com.infopro.Dependency.B.user_id</name>
<outbound type="class" confirmed="no">java.lang.String</outbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.doStatus()</inbound>
</feature>
</class>
<class confirmed="yes">
<name>com.infopro.Dependency.C</name>
<outbound type="class" confirmed="no">java.lang.Object</outbound>
<outbound type="class" confirmed="no">javax.ejb.Remote</outbound>
<inbound type="class" confirmed="yes">com.infopro.Dependency.B</inbound>
<feature confirmed="yes">
<name>com.infopro.Dependency.C.doStatus()</name>
</feature>
</class>
</package>
<package confirmed="no">
<name>java.lang</name>
<class confirmed="no">
<name>java.lang.Object</name>
<inbound type="class" confirmed="yes">com.infopro.Dependency.A</inbound>
<inbound type="class" confirmed="yes">com.infopro.Dependency.B</inbound>
<inbound type="class" confirmed="yes">com.infopro.Dependency.C</inbound>
<feature confirmed="no">
<name>java.lang.Object.Object()</name>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.A()</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.B()</inbound>
</feature>
</class>
<class confirmed="no">
<name>java.lang.String</name>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.check(java.lang.String, java.lang.String)</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.doStatus()</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.name</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.stat</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.A.user_id</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.check(java.lang.String, java.lang.String)</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.doStatus()</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.name</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.stat</inbound>
<inbound type="feature" confirmed="yes">com.infopro.Dependency.B.user_id</inbound>
</class>
</package>
<package confirmed="no">
<name>javax.ejb</name>
<class confirmed="no">
<name>javax.ejb.Remote</name>
<inbound type="class" confirmed="yes">com.infopro.Dependency.C</inbound>
</class>
<class confirmed="no">
<name>javax.ejb.Stateless</name>
<inbound type="class" confirmed="yes">com.infopro.Dependency.A</inbound>
<inbound type="class" confirmed="yes">com.infopro.Dependency.B</inbound>
</class>
</package>
</dependencies>我想以这种格式创建csv文件的输出。
classname1, outbound.
classname1, outbound.
. .
. .
classname1, inbound.
. .
. .
classname2, outbound.
. .
classname2, inbound.以此类推..
现在我面临的挑战是,每个班级的入站和出站数量都不同,而且各不相同。所以我必须为它指定循环。另外,我只需要在类名中包含"com“关键字或字符串,不包括包名,特性名。我需要这样做xsl,以便对于我生成的所有类似的xml,我可以将其更改为csv表形式,以便进一步处理所需的数据。
我创建的xsl如下所示,但我仍然面临一些bug和问题
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="class[contains(.//text(), 'com')]">
<xsl:text></xsl:text><xsl:value-of select="name"/><xsl:if test="@confirmed='no'"> *</xsl:if><xsl:text> </xsl:text>
<xsl:for-each select="outbound[contains(.//text(), 'com')]">
<xsl:text disable-output-escaping="yes"> , </xsl:text><xsl:value-of select="."/><xsl:if test="@confirmed='no'"> *</xsl:if><xsl:text>
</xsl:text>
</xsl:for-each>
<xsl:for-each select="inbound[contains(.//text(), 'com')]">
<xsl:text disable-output-escaping="yes"> , </xsl:text><xsl:value-of select="."/><xsl:if test="@confirmed='no'"> *</xsl:if><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>输出结果为
com.infopro.Dependencycom.infopro.Dependency.A , com.infopro.Dependency.B.B()
, com.infopro.Dependency.B.a
com.infopro.Dependency.B , com.infopro.Dependency.C
, com.infopro.Dependency.A.A()
, com.infopro.Dependency.A.b
com.infopro.Dependency.C , com.infopro.Dependency.B
java.langjava.lang.Objectcom.infopro.Dependency.Acom.infopro.Dependency.Bcom.infopro.Dependency.Cjava.lang.Object.Object()com.infopro.Dependency.A.A()com.infopro.Dependency.B.B()java.lang.Stringcom.infopro.Dependency.A.check(java.lang.String, java.lang.String)com.infopro.Dependency.A.doStatus()com.infopro.Dependency.A.namecom.infopro.Dependency.A.statcom.infopro.Dependency.A.user_idcom.infopro.Dependency.B.check(java.lang.String, java.lang.String)com.infopro.Dependency.B.doStatus()com.infopro.Dependency.B.namecom.infopro.Dependency.B.statcom.infopro.Dependency.B.user_idjavax.ejbjavax.ejb.Remotecom.infopro.Dependency.Cjavax.ejb.Statelesscom.infopro.Dependency.Acom.infopro.Dependency.B类似表格的排列几乎发生了,但仍然存在包名的问题,仍然坚持使用第一个类名,并在最后使用一些不需要的java字符串。希望能得到指导和帮助。谢谢
发布于 2011-04-04 15:23:24
嗯,你不需要做任何显式的循环。你可以对模板做任何你想做的事情。
要有效地编写XSLT,必须从转换的角度进行考虑。想一想,“我想把输入中的一些东西转换成输出中的一些东西。”这些是什么东西?你没有在你的问题中清楚地表达它们,也有可能你在你的设计中没有表达它们。
看起来您想要的是将每个package元素转换为输出中的一行。所以你需要一个模板。每行的第一行是包名(即name元素的文本内容),最后一行是换行符。所以从这个开始吧:
<xsl:template match="/">
<xsl:apply-templates select="dependencies/package"/>
</xsl:template>
<xsl:template match="package">
<xsl:value-of select="name/text()"/>
<!-- something will go in here -->
<xsl:text>
</xsl:text>
</xsl:template>如果在输入文档中运行转换(假设已将其放入实际样式表中),则应该会得到一个包含所有包名的简单列表作为输出。
现在,您希望将outbound和inbound元素的内容作为额外的逗号分隔元素添加到每一行。转变是什么?如果confirmed属性等于no,则每个元素都需要转换为一段文本,其中包含逗号、元素的文本内容和星号。
这很容易实现:只需创建一个包含这些元素的模板,并在package模板中应用它们。由于您只希望显示文本内容以con.开头的元素,因此应在应用模板时添加谓词:
<xsl:template match="package">
<xsl:value-of select="name/text()"/>
<xsl:apply-templates select="output[contains(text(), '.com')]"/>
<xsl:apply-templates select="input[contains(text(), '.com')]"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="output|input">
<xsl:text>, </xsl:text>
<xsl:value-of select="text()"/>
<xsl:if test="@confirmed='no'">
<xsl:text> *</xsl:text>
</xsl:text>
</xsl:text>关于这种设计和实现方法,有两点很重要:首先,您使用模板来转换节点,而不是试图在一种不适合它的语言中使用过程化编程。
其次,您只需要转换显式选择的节点。现在您在输出的末尾得到垃圾信息的原因是,您已经将模板应用到了您认为没有应用它们的节点:您没有创建应用于文档根目录的模板,因此XSLT处理器会将内置模板应用于它找到的每个元素。
https://stackoverflow.com/questions/5534190
复制相似问题