【问题标题】:XSLT 1.0 textlist to individual elements and duplicate removalXSLT 1.0 文本列表到单个元素和重复删除
【发布时间】:2012-07-13 08:42:14
【问题描述】:

我有以下 XML 文档:

<?xml version="1.0" encoding="UTF-8"?>
<cars>
    <car body="Wagon">
        <text>Red</text>
    </car>
    <car body="Sedan">
        <text>Yellow</text>
    </car>
    <car body="Sedan">
        <text></text>
    </car>
    <car body="Wagon">
        <textlist>
            <text>Red</text>
            <text>Green</text>
            <text>Black</text>
            <text>Blue</text>
        </textlist>
    </car>
    <car body="Sedan">
        <textlist>
            <text>Yellow</text>
            <text>Orange</text>
        </textlist>
    </car>
    <car body="Fastback">
        <textlist>
            <text>Yellow</text>
            <text>Red</text>
            <text>Green</text>
            <text>Black</text>
            <text>Blue</text>
        </textlist>
    </car>
    <car body="Fastback">
        <textlist>
            <text>Pink</text>
            <text>Red</text>
            <text>Orange</text>
        </textlist>
    </car>
</cars>

使用 XSLT 1.0 我需要将 XML 文档转换为这种格式:

<?xml version="1.0" encoding="UTF-8"?>
<cars>
    <car type="Wagon">Red</car>
    <car type="Sedan">Yellow</car>
    <car type="Wagon">Green</car>
    <car type="Wagon">Black</car>
    <car type="Wagon">Blue</car>
    <car type="Sedan">Orange</car>
</cars>

注意:

  1. body="Fastback" 被排除在外
  2. 排除重复项(Red Wagon 出现两次)
  3. 文本列表中的多个项目被单独放置 输出 XML 中的元素
  4. 忽略空值

【问题讨论】:

    标签: xml xslt xslt-1.0


    【解决方案1】:

    这是一个示例:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output indent="yes"/>
    
    <xsl:key name="k1" 
      match="car[not(@body = 'Fastback')]//text"
      use="concat(ancestor::car/@body, '|', .)"/>
    
    <xsl:template match="cars">
      <xsl:copy>
        <xsl:apply-templates select="car[not(@body =  'Fastback')]//text
          [generate-id() = generate-id(key('k1', concat(ancestor::car/@body, '|', .))[1])]"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="text">
      <car type="{ancestor::car/@body}">
        <xsl:value-of select="."/>
      </car>
    </xsl:template>
    
    </xsl:stylesheet>
    

    它使用 Muechian 分组,如果您不熟悉 XSLT 1.0 方法,请参阅 http://www.jenitennison.com/xslt/grouping/muenchian.xml

    【讨论】:

    • 试图理解这是如何工作的,key('k1', concat(ancestor::car/@body, '|', .))[1] 末尾的方括号是什么意思??
    • [1] 选择键控组的头部。因此,xsl:apply-templates 应用于每个组的第一个节点,而不是每个组的每个节点。
    • 方括号中的表达式是谓词,带有整数的表达式(例如[1])是位置谓词,[position() = 1]的缩写形式。所以key('key-name', some key value expression) 选择一个节点集,并且使用位置谓词key('key-name', some key value expression)[1],我们只选择key 函数调用返回的节点集中的第一个节点(按文档顺序)。使用完整的谓词[generate-id() = generate-id(key('k1', concat(ancestor::car/@body, '|', .))[1])],我们确保只处理每个组中的第一项,请参阅链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多