使用 XSLT 1.0 对相似标签进行分组的 XSLT 转换 [英] XSLT transformation to group similar tags with XSLT 1.0

查看:32
本文介绍了使用 XSLT 1.0 对相似标签进行分组的 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>

现在我想对它进行转换,以便根据 name<将 person 标签、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 1.0 转换.

I want to do an XSLT 1.0 transformation 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>

注意:我收到了一个关于 XSLT 2.0 的答案,但现在我正在寻找 XSLT 1.0 的解决方案.

Note: I received an answer for XSLT 2.0, But now I'm looking for a solution with XSLT 1.0.

推荐答案

XSLT 1.0 中执行此操作的一种方法是:

One way to do this in XSLT 1.0 would be:

<xsl:stylesheet version="1.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="citizen-by-name" match="citizens/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('citizen-by-name', name)/city "/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

<小时>

另一种选择是使用慕尼黑方法分组 来自两个分支的 person 元素,按它们的 name.


Another option would be to use the Muenchian method to group the person elements from both branches by their name.

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆