【问题标题】:XSLT transformation to group similar tagsXSLT 转换对相似标签进行分组
【发布时间】:2016-08-26 18:08:07
【问题描述】:

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

<?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>

现在我想对此进行转换,以便 person 标记、playerscitizens 部分基于 name 标记合并在一起。

这是我需要的输出。

<?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 转换。我尝试了很多没有运气的东西。感谢您对此的帮助。

更新:我试过了。

<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 标签。请指导我。

   <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 版本?

标签: xml xslt xslt-1.0 xslt-2.0


【解决方案1】:

这是您可以查看的一种方式:

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>

这是另一个:

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>

【讨论】:

  • 非常感谢。我也在尝试,并用我到目前为止得到的内容更新了我的问题。你能帮我理解我应该改变什么吗?
  • 您能编辑一下并作为另一个答案发布吗?
  • @abhi 恐怕我不明白你的方法,也不知道如何解决它。
  • 不用担心迈克尔。谢谢你的回答。我刚刚在online-toolz.com/tools/xslt-transformation.php 中快速尝试了您的解决方案。但它给出了一个错误。是因为不支持2.0吗?
  • 不幸的是,我的处理器似乎不支持 XSLT 2.0 的某些部分。所以我必须去1.0。以前我在上面发布了错误的结果。我更新了它并创建了一个新问题。如果你有时间,请看看。 stackoverflow.com/questions/39177494/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-12
  • 1970-01-01
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
相关资源
最近更新 更多