【问题标题】:XSLT, how to fetch and output combined elementsXSLT,如何获取和输出组合元素
【发布时间】:2011-04-23 09:55:39
【问题描述】:

尊敬的社区, 如果你能给我一个关于如何改变它的建议,那就太好了:

<div>  
something  
   <title>   this title  </title>  
    something else  
</div>  

进入

<div>  
<title1>
something  </title1>  
<title2>  this title  </title2>  
<title3>  something else  </title>
</div>

不幸的是 substring-before/after 方法不能使用,因为 div 中有一个内部元素。此外,复制似乎也不适用于子字符串。您对如何转换上述 xml 有什么建议吗?

【问题讨论】:

  • 好问题,+1。请参阅我的答案,以获取与所需结果更接近(比其他解决方案)的解决方案,同时稍微更通用。 :)

标签: xml xslt


【解决方案1】:

这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="div/text()|div/*">
        <xsl:element name="title{position()}">
            <xsl:value-of select="normalize-space(self::text())"/>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

输出:

<div>
    <title1>something</title1>
    <title2> this title </title2>
    <title3>something else</title3>
</div>

【讨论】:

  • 非常感谢您的解决方案,不胜感激!
  • @Alejandro - 请注意,一旦我进行了编辑,就会发现源文档中有额外的空白。这并不是你的错,因为它最初并不清楚,而且 OP 可能没有意识到(或关心)空白可能很重要。
【解决方案2】:

这个解决方案更精确一些,同时也更通用

<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:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/*/node()">
  <xsl:element name="title{position()}">
   <xsl:copy-of select="translate(self::text()|node(), '&#xA;&#xD;', '  ')"/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时

<div>
something      
    <title>   this title  </title>
     something else
</div>

会产生更接近预期的结果(仅将 NL 或 CR 字符转换为空格):

<div>
   <title1> something           </title1>
   <title2>   this title  </title2>
   <title3>      something else </title3>
</div>

【讨论】:

    【解决方案3】:

    编辑

    我刚刚意识到我的输出与您的不匹配。
    但是@Alejandro 的解决方案是完美的,所以我希望你不会对此感到太沮丧。


    我想出了这个解决方案:

    <?xml version="1.0"?>
    <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="/">
            <xsl:element name="div">
                <xsl:apply-templates />
            </xsl:element>
        </xsl:template>
    
        <xsl:template match="div/text()|div/title/text()">
            <xsl:element name="title{position()}">
                <xsl:copy-of select="normalize-space(.)" />
            </xsl:element>
        </xsl:template>
    </xsl:stylesheet>
    

    产生这个输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <div>
        <title1>something</title1>
        <title1>this title</title1>
        <title3>something else</title3>
    </div>
    

    【讨论】:

    • 非常感谢您的解决方案,不胜感激!
    猜你喜欢
    • 2014-01-31
    • 1970-01-01
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多