【问题标题】:Grouping output using XSLT 1.0使用 XSLT 1.0 对输出进行分组
【发布时间】:2019-03-04 09:29:37
【问题描述】:

我收到了以下 XML(由某人从 Excel 电子表格中生成)

<Records>
<record>
    <Domain>Domain 1</Domain>
    <Section>Section A</Section>
    <label>Option X 1</label>
    <Keyword>Unique KW 1</Keyword>
    <Control>Checkbox</Control>
    <Default>TRUE</Default>
</record>
<record>
    <Domain>Domain 1</Domain>
    <Section>Section B</Section>
    <label>Option X 2</label>
    <Keyword>Unique KW 2</Keyword>
    <Control>Checkbox</Control>
    <Default>TRUE</Default>
</record>
<record>
    <Domain>Domain 2</Domain>
    <Section>Section A</Section>
    <label>Option X 3</label>
    <Keyword>Unique KW 3</Keyword>
    <Control>Checkbox</Control>
    <Default>TRUE</Default>
</record>
<record>
    <Domain>Domain 1</Domain>
    <Section>Section A</Section>
    <label>Option X 4</label>
    <Keyword>Unique KW 4</Keyword>
    <Control>Checkbox</Control>
    <Default>FALSE</Default>
</record>
<record>
    <Domain>Domain 1</Domain>
    <Section>Section B</Section>
    <label>Option X 5</label>
    <Keyword>Unique KW 5</Keyword>
    <Control>Checkbox</Control>
    <Default>TRUE</Default>
</record>
<record>
    <Domain>Domain 2</Domain>
    <Section>Section B</Section>
    <label>Option X 6</label>
    <Keyword>Unique KW 6</Keyword>
    <Control>Checkbox</Control>
    <Default>TRUE</Default>
</record>
<record>
    <Domain>Domain 1</Domain>
    <Section>Section A</Section>
    <label>Option X 7</label>
    <Keyword>Unique KW 7</Keyword>
    <Control>Checkbox</Control>
    <Default>TRUE</Default>
</record>
</Records>

我被要求使用 XSLT 1.0 将其转换为以下内容

<Configuration>
<Domain name="Domain 1">
    <Section name="Section A">
        <Option keyword="Unique KW 1" name="Option X 1">
            <Control type="Checkbox" default="True" />
        </Option>
        <Option keyword="Unique KW 3" name="Option X 3">
            <Control type="Checkbox" default="True" />
        </Option>
        <Option keyword="Unique KW 7" name="Option X 7">
            <Control type="Checkbox" default="True" />
        </Option>
    </Section>
    <Section name="Section B">
        <Option keyword="Unique KW 2" name="Option X 2">
            <Control type="Checkbox" default="True" />
        </Option>
        <Option keyword="Unique KW 5" name="Option X 5">
            <Control type="Checkbox" default="True" />
        </Option>
    </Section>
</Domain>
<Domain name="Domain 2">
    <Section name="Section A">
        <Option keyword="Unique KW 3" name="Option X 3">
            <Control type="Checkbox" default="True" />
        </Option>       
    </Section>
    <Section name="Section B">
        <Option keyword="Unique KW 6" name="Option X 6">
            <Control type="Checkbox" default="True" />
        </Option>       
    </Section>
</Domain>
</Configuration>

我过去曾以有限的能力使用 XSLT,但我正在努力获取单个元素(例如域和部分),我得到的输出是源中的每个元素一个,而我需要每个值 1来源(如果有意义的话)。我似乎得到了很多

Domain 而不是只有两个(Domain 1 和 Domain 2),与 Section 相同

有什么方法可以用 XSLT 1.0 做到这一点,还是我只是在浪费时间?

(另外,我给出的数据是一个示例,经过编辑以删除敏感数据和大小,还有更多的域和部分等)

(到目前为止我得到的一点点)

<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:ms="urn:schemas-microsoft-com:xslt"
            xmlns:dt="urn:schemas-microsoft-com:datatypes">
<xsl:output media-type="xml" indent="yes" />

<xsl:template match="/Records">
<Configuration>
  <xsl:for-each select="record/Domain">
    <Domain name="{text()}">
    <Section name="{../Section/text()}">
      <Option keyword="{../Keyword/text()}">
        <Control type="{../Control/text()}"/>
      </Option>
    </Section>
    </Domain>
  </xsl:for-each>
</Configuration>
</xsl:template>
</xsl:stylesheet>

编辑: 在查看 Michaels 链接(谢谢)后,我越来越近了。外部组(域)正在工作,但内部组没有

  <xsl:key name="domain-name" match="record" use="Domain" />
  <xsl:key name="section-name" match="record" use="Section" />

  <xsl:template match="/Records">
    <Configuration>
      <xsl:for-each select="record[count(. | key('domain-name', Domain)[1]) = 1]">
        <xsl:sort select="Domain" />
        <Domain name="{Domain}">
          <xsl:for-each select="record[count(. | key('section-name', Section)[1]) = 1]">
            <xsl:sort select="Section" />
              <Section name="{Section}">
                <Option keyword="{Keyword/text()}">
                  <Control type="{Control/text()}"/>
                </Option>
              </Section>
            </xsl:for-each>
          </Domain>
        </xsl:for-each>
      </Configuration>
    </xsl:template>

给我

  <Configuration>
    <Domain name="Domain 1" />
    <Domain name="Domain 2" />
  </Configuration>

【问题讨论】:

  • 我认为这是可能的。请贴出你目前已经实现的 XSLT 代码。
  • 这里有数百个分组示例。从这里开始:jenitennison.com/xslt/grouping/muenchian.html,如果遇到任何具体问题,请回来。
  • 感谢@michael.hor257k 链接帮助。现在的具体问题是内部分组(Section)。我在原帖中添加了一些信息。

标签: xml xslt xslt-1.0


【解决方案1】:

对于您的内部分组,您将 Section 元素分组到 Domain 中,因此两个元素都需要在键内

<xsl:key name="section-name" match="record" use="concat(Domain, '|', Section)" />

然后需要更改内部xsl:for-each 以使用新的密钥格式。但也因为您正在执行xsl:for-each select="group....",这将不起作用,因为您当前位于record 上,因此内部xsl:for-each 正在寻找一个也称为record 的子元素。它应该看起来像这样,它只考虑当前Domain 值的record 元素

<xsl:for-each select="key('domain-name', Domain)[count(. | key('section-name', concat(Domain, '|', Section))[1]) = 1]">

试试这个 XSLT

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

  <xsl:key name="domain-name" match="record" use="Domain" />
  <xsl:key name="section-name" match="record" use="concat(Domain, '|', Section)" />

  <xsl:template match="/Records">
    <Configuration>
      <xsl:for-each select="record[count(. | key('domain-name', Domain)[1]) = 1]">
        <xsl:sort select="Domain" />
        <Domain name="{Domain}">
          <xsl:for-each select="key('domain-name', Domain)[count(. | key('section-name', concat(Domain, '|', Section))[1]) = 1]">
            <xsl:sort select="Section" />
              <Section name="{Section}">
                <Option keyword="{Keyword/text()}">
                  <Control type="{Control/text()}"/>
                </Option>
              </Section>
            </xsl:for-each>
          </Domain>
        </xsl:for-each>
      </Configuration>
    </xsl:template>
</xsl:stylesheet>

看起来您还需要在Keyword 上进行第三级分组,但您现在应该能够解决这个问题(您需要考虑DomainSectionKeyword 的密钥)

【讨论】:

    猜你喜欢
    • 2016-01-25
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 2015-07-30
    • 2014-11-16
    • 1970-01-01
    相关资源
    最近更新 更多