首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用xslt对xml元素进行分组

如何使用xslt对xml元素进行分组
EN

Stack Overflow用户
提问于 2012-03-08 21:27:24
回答 3查看 279关注 0票数 0

我需要将现有的XML结构转换为另一个XML结构。

XMLSource:

代码语言:javascript
复制
 <?xml version="1.0"?>
  <content>
                <first>Paragraph-1</first>
                <comment>Comment-1</comment>
                <likes>like-1</likes>

                <first>Paragraph-2</first>
                <comment>Comment-2</comment>
                <likes>like-2</likes>

                <first>Paragraph-3</first>
                <comment>Comment-3</comment>

 </content>

需要的输出格式:

代码语言:javascript
复制
<content1>
 <block>
  <aaa>Paragraph-1</aaa>
  <bbb>Comment-1</bbb>
  <ccc>like-1</ccc>
 </block>
 <block>
  <aaa>Paragraph-2</aaa>
  <bbb>Comment-2</bbb>
  <ccc>like-2</ccc>
 </block>
 <block>
  <aaa>Paragraph-3</aaa>
  <bbb>Comment-3</bbb>
 </block>
</content1>

如何使用XSLT来实现这一点。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-08 23:56:43

下面是我更喜欢的另一个XSLT 1.0选项,因为所有东西都有自己的模板。我认为这比使用多个xsl:for-each更容易增加样式表的复杂性。

XML输入

代码语言:javascript
复制
<content>
  <first>Paragraph-1</first>
  <likes>like-1</likes>

  <first>Paragraph-2</first>
  <comment>Comment-2</comment>
  <likes>like-2</likes>

  <first>Paragraph-3</first>
  <comment>Comment-3</comment>

  <first>Paragraph-4</first>
  <comment>Comment-4</comment>
  <likes>like-4</likes>
</content>

XSLT 1.0

代码语言:javascript
复制
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="content">
    <content1>
      <xsl:apply-templates select="node()|@*"/>
    </content1>
  </xsl:template>

  <xsl:template match="first">
    <block>
      <aaa>
        <xsl:apply-templates select="node()|@*"/>
      </aaa>
      <xsl:apply-templates select="following-sibling::*[1][name()='comment']" mode="mod"/>
      <xsl:apply-templates select="following-sibling::*[1][name()='likes']" mode="mod"/>      
    </block>
  </xsl:template>

  <xsl:template match="comment" mode="mod">
    <bbb>
      <xsl:apply-templates select="node()|@*"/>
    </bbb>
    <xsl:apply-templates select="following-sibling::*[1][name()='likes']" mode="mod"/>
  </xsl:template>

  <xsl:template match="likes" mode="mod">
    <ccc>
      <xsl:apply-templates select="node()|@*"/>
    </ccc>
  </xsl:template>

  <xsl:template match="comment|likes"/>

</xsl:stylesheet>

XML输出

代码语言:javascript
复制
<content1>
   <block>
      <aaa>Paragraph-1</aaa>
      <ccc>like-1</ccc>
   </block>
   <block>
      <aaa>Paragraph-2</aaa>
      <bbb>Comment-2</bbb>
      <ccc>like-2</ccc>
   </block>
   <block>
      <aaa>Paragraph-3</aaa>
      <bbb>Comment-3</bbb>
   </block>
   <block>
      <aaa>Paragraph-4</aaa>
      <bbb>Comment-4</bbb>
      <ccc>like-4</ccc>
   </block>
</content1>
票数 0
EN

Stack Overflow用户

发布于 2012-03-08 22:12:04

请观察下面健壮的XML,如果您需要更多的建议,请让我知道。:)我已经提供了比你所要求的更多。

输入XML:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
    <content>
      <first>Paragraph-1</first>
      <likes>like-1</likes>

      <first>Paragraph-2</first>
      <comment>Comment-2</comment>
      <likes>like-2</likes>

      <first>Paragraph-3</first>
      <comment>Comment-3</comment>

      <first>Paragraph-4</first>
      <comment>Comment-4</comment>
      <likes>like-4</likes>
    </content>

XSLT代码:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

  <xsl:template match="content">
    <xsl:element name="content1">
      <xsl:apply-templates select="node()|@*"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="first">
    <xsl:variable name="count" select="count(following-sibling::first)"/>
    <xsl:element name="block">
      <aaa>
        <xsl:apply-templates select="node()|@*"/>
      </aaa>
      <xsl:for-each select="following-sibling::comment[1][count(following-sibling::first) = $count]">
        <bbb>
          <xsl:apply-templates select="node()|@*"/>
        </bbb>
      </xsl:for-each>
      <xsl:for-each select="following-sibling::likes[1][count(following-sibling::first) = $count]">
        <ccc>
          <xsl:apply-templates select="node()|@*"/>
        </ccc>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>
  <xsl:template match="comment|likes"/>

</xsl:stylesheet>

输出XML:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<content1>
  <block>
    <aaa>Paragraph-1</aaa>
    <ccc>like-1</ccc>
  </block>

  <block>
    <aaa>Paragraph-2</aaa>
    <bbb>Comment-2</bbb>
    <ccc>like-2</ccc>
  </block>

  <block>
    <aaa>Paragraph-3</aaa>
    <bbb>Comment-3</bbb>
  </block>

  <block>
    <aaa>Paragraph-4</aaa>
    <bbb>Comment-4</bbb>
    <ccc>like-4</ccc>
  </block>
</content1>

这就像gem一样!:D

票数 2
EN

Stack Overflow用户

发布于 2012-03-08 22:15:24

下面是一个XSLT 2.0示例:

代码语言:javascript
复制
<xsl:stylesheet
  version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="start-name" select="'a'"/>
  <xsl:param name="nchars" select="3"/>
  <xsl:variable name="start-index" select="string-to-codepoints($start-name)"/>

  <xsl:template match="content">
    <content1>
      <xsl:for-each-group select="*" group-starting-with="first">
        <block>
          <xsl:apply-templates select="current-group()"/>
        </block>
      </xsl:for-each-group>
    </content1>
  </xsl:template>

  <xsl:template match="content/*">
    <xsl:variable name="pos" select="position()"/>
    <xsl:element name="{string-join(for $c in 1 to $nchars return codepoints-to-string($pos - 1 + $start-index), '')}">
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9618374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档