XSL删除相同代码中的空节点

时间:2010-09-10 12:51:53

标签: xml svn xslt ant

我创建了以下XSL样式表,它接受一个XML数据包(从SVN给我)并将所有不包含文本“archive”的“entry”节点转换为以逗号分隔的列表我的ANT脚本。示例XML文件看起来像这样....

<?xml version="1.0"?>
<lists>
   <list path="https://mydomain.com/branches">
      <entry kind="dir">
         <name>James_Work</name>
         <commit revision="2209">
            <author>James</author>
            <date>2010-09-02T11:02:08.584250Z</date>
         </commit>
      </entry>
   </list>
</lists>

......而我的XSL就是这个......

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes" />

   <xsl:variable name="selectionPropertyList">
      <xsl:for-each select="lists/list/entry[name!='archive']">svnType/<xsl:value-of select="name" />
         <xsl:if test="position()!=last()">,</xsl:if> 
      </xsl:for-each>
   </xsl:variable>

   <xsl:template match="/">
      <root>
         <svnType><xsl:copy-of select="$selectionPropertyList" /></svnType>
      </root>
   </xsl:template>
</xsl:stylesheet>

我遇到的问题是当我收到空包时。例如,如果我调用当前为空的SVN分支文件夹,并在我的ANT列表中以空条目结束,则可能会发生这种情况。

示例XML数据包如下所示

<?xml version="1.0"?>
<lists>
   <list path="https://mydomain.com/branches">
   </list>
</lists>

有没有人知道我可以某种方式从我的列表中过滤掉这些空数据包?

谢谢, 詹姆斯

P.S。我已经尝试了这里给出的提示,但它与我在这里尝试做的不太匹配。 http://www.tek-tips.com/viewthread.cfm?qid=1088712&page=1

更新

更大的输入示例:

<?xml version="1.0"?>
<lists>
<list path="https://mydomain.com/website/branches">
<entry kind="dir">
   <name>ITNAM-752</name>
   <commit revision="2171">
       <author>jcb4337</author>
       <date>2010-08-30T15:13:21.006125Z</date>
   </commit>
</entry>
<entry kind="dir">
   <name>JCB4337-577</name>
   <commit revision="2171">
      <author>jcb4337</author>
      <date>2010-08-30T15:13:21.006125Z</date>
   </commit>
 </entry>
 <entry kind="dir">
     <name>JCB4337-726</name>
     <commit revision="2209">
        <author>jcb4337</author>
        <date>2010-09-02T11:02:08.584250Z</date>
      </commit>
  </entry>
  <entry kind="dir">
      <name>JCB4337-808</name>
      <commit revision="2206">
          <author>jcb4337</author>
          <date>2010-09-01T13:01:51.693625Z</date>
      </commit>
  </entry>
  <entry kind="dir">
        <name>JCB4337-847</name>
        <commit revision="2172">
            <author>jcb4337</author>
            <date>2010-08-30T15:14:12.803000Z</date>
         </commit>
  </entry>
 </list>
</lists>

我需要从XSL返回的输出是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<root>
 <branches>branches/ITNAM-752,branches/JCB4337-577,branches/JCB4337-726,branches/JCB4337-808,branches/JCB4337-847</branches>
</root>

我已经使用了上面的@Alejandro代码,我想我就在那里。但是我一路上得到了一些奇怪的结果。输出示例是:

<?xml version="1.0" encoding="UTF-8"?>
     <root>
      <branches>

          branches/ITNAM-752,
          branches/JCB4337-577,
          branches/JCB4337-726,
          branches/JCB4337-808,
          branches/JCB4337-847,

      </branches>
      </root>

因此...

1)在列表元素之间获得大量空白。

2)在结果结束时我还有一个额外的逗号。

3)当我尝试将其应用于我们的SVN标签文件夹时,我得到了一些奇怪的结果。标签略有不同,因为它包含我要从任何结果中排除的“存档”文件夹。

目前,当我使用相同的代码输出tags文件夹时,我得到了这个......

<?xml version="1.0" encoding="UTF-8"?>
  <root>
    <tags>


        archive

        jcb4337
        2010-08-31T08:56:51.006125Z


         tags/milestone 1-0-0,
         tags/milestone 1-0-0b,
         tags/milestone 1-0-1,
         tags/milestone 1-0-10,
         tags/milestone 1-0-11,
         tags/milestone 1-0-2,
         tags/milestone 1-0-3,
         tags/milestone 1-0-4,
         tags/milestone 1-0-5,
         tags/milestone 1-0-6,
         tags/milestone 1-0-7,
         tags/milestone 1-0-8,
         tags/milestone 1-0-9,

      </tags>
    </root>

使用@Alejandro解决方案,出现了大量的空白和存档,以及所有时间戳,作者信息。

顺便说一句,如果你想知道我已经让XT在XSL完成之后直接替换了令牌。它正在取代XML中的短语svnType。我想不出使用XSL在每个节点上应用前缀分支/标签的方法。

希望这一切都有所帮助,并再次感谢大家的努力。 XSL对我来说有点像黑色艺术: - )。

3 个答案:

答案 0 :(得分:1)

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*"/>
    <xsl:template match="list/entry[name!='archive']">
        <xsl:value-of select="concat('svnType/',
                                     name,
                                     substring(',',
                                               1,
                                               position()!=last())
                                     )"/>
    </xsl:template>
    <xsl:template match="/">
        <root>
            <svnType>
                <xsl:choose>
                    <xsl:when test="lists/list/entry/name!='archive'">
                        <xsl:apply-templates/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:comment>There is no entry
                                     without "archive" name</xsl:comment>
                    </xsl:otherwise>
                </xsl:choose>
            </svnType>
        </root>
    </xsl:template>
</xsl:stylesheet>

输出:

<root>
    <svnType>svnType/James_Work</svnType>
</root>

使用此输入:

<lists>
    <list path="https://mydomain.com/branches"></list>
</lists>

输出:

<root>
    <svnType>
        <!--There is no entry with "archive" name-->
    </svnType>
</root>

编辑xsl:strip-space仅从输入源中剥离空白文本节点。

编辑:另外,采用拉式方法:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*"/>
    <xsl:template match="entry[name!='archive']">
        <xsl:call-template name="output"/>
        <xsl:text>,</xsl:text>
    </xsl:template>
    <xsl:template match="entry[name!='archive'][last()]"
                  name="output"
                  priority="1">
        <xsl:value-of select="concat('svnType/',name)"/>
    </xsl:template>
    <xsl:template match="lists">
        <root>
            <svnType>
                <xsl:apply-templates/>
            </svnType>
        </root>
    </xsl:template>
    <xsl:template match="list[not(entry/name!='archive')]">
        <xsl:comment>There is no entry without "archive" name</xsl:comment>
    </xsl:template>
</xsl:stylesheet>

两个样式表输出:

<root>
   <svnType>svnType/ITNAM-752,svnType/JCB4337-577,svnType/JCB4337-726,svnType/JCB4337-808,svnType/JCB4337-847</svnType>
</root>

答案 1 :(得分:0)

将匹配表达式更改为:

<xsl:template match="/lists[list/entry[name != 'archive']]">

应该有用。

(我也使用apply-templates而不是$ selectionPropertyList,但这是另一个问题)

答案 2 :(得分:0)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />

<xsl:template match="list">
    <xsl:text>svnType/</xsl:text><xsl:value-of select="entry/name" />
    <xsl:if test="position()!=last()">,</xsl:if>
</xsl:template>

<xsl:template match="/">
    <root>
        <svnType>
            <xsl:apply-templates select="//list[entry/name!='archive'][*]" />
        </svnType>
    </root>
</xsl:template>
</xsl:stylesheet>

基本上[*]表示list元素应该有子节点。