XSLT包装重复行,不区分大小写



我正在尝试使用 XSLT 编写一个循环,以便它自动将所有具有相同 ID 但以不区分大小写的方式的项目分组。不幸的是,我尝试解析的数据是客户端驱动的,因此我无法在加载之前更改它。不管这里是XML结构...

<Document>
    <Row>
        <Cell>ID</Cell>
    </Row>
    <Row>
        <Cell>hi</Cell>
    </Row>
    <Row>
        <Cell>Hi</Cell>
    </Row>
    <Row>
        <Cell>Hello</Cell>
    </Row>
    <Row>
        <Cell>Hello</Cell>
    </Row>
    <Row>
        <Cell>Hola</Cell>
    </Row>
</Document>

这是我当前正在使用的 XSLT

...
  <xsl:template match="Document">
    <NewDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <xsl:for-each select="//Row[position() &gt; 1]/Cell[1][not(.=preceding::Row/Cell[1])]">
        <xsl:variable name="currentOrderID" select="." />
        <xsl:variable name="currentOrderGroup" select="//Row[Cell[1] = $currentOrderID]" />
        <MainID>
          <xsl:value-of select="$currentOrderGroup[1]/Cell[1]"/>
        </MainID>
        <IDs>
          <xsl:for-each select="$currentOrderGroup">
            <id>
              <xsl:value-of select="Cell[1]"/>
            </id>
          </xsl:for-each>
        </IDs>
      </xsl:for-each>
    </NewDocument>
  </xsl:template>

这只是以CaSe SeNSiTiVe的方式按预期结束事情......我一直在尝试在那里使用翻译以使所有内容都大写,但是我似乎无法使语法恰到好处。

我在这里试图实现的结果是这样的:

<NewDocument>
  <MainID>hi</MainID>
  <IDs>
    <id>hi</id>
    <id>Hi</id>
  </IDs>  
  <MainID>Hello</MainID>
  <IDs>
    <id>Hello</id>
    <id>Hello</id>
  </IDs>
  <MainID>Hola</MainID>
  <IDs>
    <id>Hola</id>
  </IDs>
</NewDocument>

似乎找不到任何专门满足我需求的东西。谢谢!

在 XSLT1.0 中,要将字符串转换为小写,您需要在 xpath 中使用相当繁琐的翻译函数。

translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')

此外,您的问题是分组问题之一,在 XSLT1.0 中,这通常意味着一种称为 Meunchian 分组的技术。为此,您首先定义一个键来查找所需组中的项目

<xsl:key 
   name="Cell" 
   match="Cell" 
   use="translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
在这里,我们根据单元格

的(小写)文本内容查找单元格。

要查找每个组中的第一个元素,请在 XML 中查找 Cell 元素,这些元素也恰好是查找键中出现的第一个元素

<xsl:apply-templates 
   select="Row/Cell
   [generate-id() 
    = generate-id(
       key('Cell', 
         translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))[1])]"/>

然后,当您匹配第一个元素时,您可以通过查看键来匹配组中的所有元素。

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="Cell" match="Cell" use="translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
   <xsl:template match="Document">
      <NewDocument>
         <xsl:apply-templates select="Row/Cell[generate-id() = generate-id(key('Cell', translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))[1])]"/>
      </NewDocument>
   </xsl:template>
   <xsl:template match="Cell">
      <MainID>
         <xsl:value-of select="."/>
      </MainID>
      <IDs>
         <xsl:apply-templates select="key('Cell', translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))" mode="group"/>
      </IDs>
   </xsl:template>
   <xsl:template match="Cell" mode="group">
      <id>
         <xsl:value-of select="."/>
      </id>
   </xsl:template>
</xsl:stylesheet>

请注意使用 mode 属性来区分与 Cell 元素匹配的两个模板。

应用于 XML 时,将输出以下内容:

<NewDocument>
   <MainID>ID</MainID>
   <IDs>
      <id>ID</id>
   </IDs>
   <MainID>hi</MainID>
   <IDs>
      <id>hi</id>
      <id>Hi</id>
   </IDs>
   <MainID>Hello</MainID>
   <IDs>
      <id>Hello</id>
      <id>Hello</id>
   </IDs>
   <MainID>Hola</MainID>
   <IDs>
      <id>Hola</id>
   </IDs>
</NewDocument>

请注意,我不确定如何处理以 ID 作为值的单元格,所以我把它留了下来。如果确实要排除它,只需将此行添加到 XSLT 中即可

<xsl:template match="Cell[. = 'ID']" />

相关内容

  • 没有找到相关文章

最新更新