如何使用头节点的元素重命名通用 XML 元素

How to rename generic XML elements using the elements of a header node

我从无法操作的在线服务获得 XML 输出。 TableHeader 节点包含列名称。使用 XSLT 1.0,如何使用 TableHeader?

中的元素重命名通用 Attribute 元素

XML 输入:

<?xml version="1.0" encoding="UTF-8"?>
<SearchResults>
    <TableHeader>
        <ColumnName>Surname</ColumnName>
        <ColumnName>FirstNames</ColumnName>
        <ColumnName>Gender</ColumnName>
        <ColumnName>Age</ColumnName>
    </TableHeader>
    <Object>
        <Attribute>Linder</Attribute>
        <Attribute>Sophie</Attribute>
        <Attribute>Female</Attribute>
        <Attribute/>
    </Object>
    <Object>
        <Attribute>?</Attribute>
        <Attribute>Thomas</Attribute>
        <Attribute>Male</Attribute>
        <Attribute>26</Attribute>
    </Object>
    <Object>
        <Attribute>Akona</Attribute>
        <Attribute>Lettie</Attribute>
        <Attribute>Female</Attribute>
        <Attribute>35</Attribute>
    </Object>
    <Object>
        <Attribute>Linder</Attribute>
        <Attribute>Fred</Attribute>
        <Attribute>Male</Attribute>
        <Attribute>38</Attribute>
    </Object>
    <Object>
        <Attribute>Akona</Attribute>
        <Attribute>Alicia</Attribute>
        <Attribute>Female</Attribute>
        <Attribute/>
    </Object>
</SearchResults>

期望输出:

<?xml version="1.0" encoding="UTF-8"?>
<SearchResults>
    <Object>
        <Surname>Linder</Surname>
        <FirstNames>Sophie</FirstNames>
        <Gender>Female</Gender>
        <Age/>
    </Object>
    <Object>
        <Surname>?</Surname>
        <FirstNames>Thomas</FirstNames>
        <Gender>Male</Gender>
        <Age>26</Age>
    </Object>
    <Object>
        <Surname>Akona</Surname>
        <FirstNames>Lettie</FirstNames>
        <Gender>Female</Gender>
        <Age>35</Age>
    </Object>
    <Object>
        <Surname>Linder</Surname>
        <FirstNames>Fred</FirstNames>
        <Gender>Male</Gender>
        <Age>38</Age>
    </Object>
    <Object>
        <Surname>Akona</Surname>
        <FirstNames>Alicia</FirstNames>
        <Gender>Female</Gender>
        <Age/>
    </Object>
</SearchResults>

我是 XSLT 的新手,所以我没有取得太大进展,但这是我目前的尝试。我想我也许可以使用 xsl:variable 来设置列名,然后将它们用作元素标签,但我确信一定有更好的方法。此外,理想情况下,它应该适用于可变数量的列。

<?xml version="1.0" encoding="UTF-8"?>

<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:variable name ="column1" select ="(ColumnName)[1]" />
  <xsl:template match ="Object">
    <Object>
      <Surname>
        <xsl:value-of select="(Attribute)[1]"/>
      </Surname>
      <FirstName>
        <xsl:value-of select="(Attribute)[2]"/>
      </FirstName>
      <Gender>
        <xsl:value-of select="(Attribute)[3]"/>
      </Gender>
      <Age>
        <xsl:value-of select="(Attribute)[4]"/>
      </Age>
    </Object>
  </xsl:template>

</xsl:stylesheet>

我的最终目标是能够使用 Muenchian 方法对这些元素进行分组,但我的理解是拥有更具描述性的元素名称会使这变得容易得多。如果它可以在不重命名的情况下一步实现,请在评论中告诉我,我将 post 对此提出一个单独的问题。

只要提供的列名也是有效的,这应该对您有用 XML 元素名称:

XSLT 1.0

<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:variable name="column-names" select="/SearchResults/TableHeader/ColumnName" />

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

<xsl:template match="Attribute">
    <xsl:variable name="i" select="position()" />
    <xsl:element name="{$column-names[$i]}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

<xsl:template match="TableHeader"/>

</xsl:stylesheet>