转换以对相似标签进行分组

转换以对相似标签进行分组

本文介绍了XSLT 转换以对相似标签进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个带有 playerscitizens 部分的 XML.每个部分都有多个 person 标签.

I have this XML with players and citizens sections. Each section has multiple person tags.

<?xml version="1.0" encoding="UTF-8"?>
<test>
   <players>
      <person>
         <name>joe</name>
         <age>20</age>
      </person>
      <person>
         <name>sam</name>
         <age>23</age>
      </person>
   </players>
   <citizens>
      <person>
         <name>joe</name>
         <city>ny</city>
      </person>
      <person>
         <name>sam</name>
         <city>london</city>
      </person>
   </citizens>
</test>

现在我想对它进行转换,以便根据 nameperson 标签、playerscitizens 部分合并在一起/code> 标签.

Now I want to transform this so that person tags of, players and citizens sections are merged together based on name tag.

这是我需要的输出.

<?xml version="1.0" encoding="UTF-8"?>
<test>
   <players>
      <person>
         <name>joe</name>
         <age>20</age>
         <city>ny</city>
      </person>
      <person>
         <name>sam</name>
         <age>23</age>
         <city>london</city>
      </person>
   </players>
</test>

我想为此进行 XSLT 转换.我尝试了很多东西都没有运气.感谢您对此的帮助.

I want to do an XSLT transformation for this. I tried lots of stuff without luck. Appreciate some help for this.

更新:我试过了.

<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:variable name="citizens" select="/test/citizens"/>
    <xsl:template match="/test/players">
        <players>
            <xsl:apply-templates select="person"/>
        </players>
    </xsl:template>

    <xsl:template match="person">
        <xsl:variable name="data1" select="."/>
        <xsl:variable name="data2" select="/test/citizens/person[name=current()/name]/."/>
        <person>
            <xsl:copy-of select="$data1/*"/>
            <xsl:for-each select="$data2/*">
                <xsl:variable name="element2" select="name(.)"/>
                <xsl:if test="count($data1/*[name()=$element2])=0">
                    <xsl:copy-of select="."/>
                </xsl:if>
            </xsl:for-each>
        </person>
    </xsl:template>
</xsl:stylesheet>

这几乎是正确的.我只想去掉最后 2 个 person 标签.请指导我.

It's almost correct. I just want to get rid of last 2 person tags. Please guide me.

   <players>
      <person>
         <name>joe</name>
         <age>20</age>
         <city>ny</city>
      </person>
      <person>
         <name>sam</name>
         <age>23</age>
         <city>london</city>
      </person>
   </players>
   <person>
      <name>joe</name>
      <city>ny</city>
   </person>
   <person>
      <name>sam</name>
      <city>london</city>
   </person>

推荐答案

您可以通过以下方式查看:

Here's one way you could look at it:

XSLT 2.0

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

<xsl:key name="person-by-name" match="person" use="name" />

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

<xsl:template match="/test">
    <xsl:copy>
        <xsl:apply-templates select="players"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="person">
    <xsl:copy>
        <xsl:apply-templates/>
        <xsl:copy-of select="key('person-by-name', name, ../../citizens)/city "/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

这是另一个:


Here's another:

XSLT 2.0

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

<xsl:template match="/test">
    <xsl:copy>
        <players>
            <xsl:for-each-group select="*/person" group-by="name">
                <person>
                    <xsl:copy-of select="name"/>
                    <xsl:copy-of select="current-group()/*[not(self::name)]"/>
                </person>
            </xsl:for-each-group>
        </players>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

这篇关于XSLT 转换以对相似标签进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 14:30