【问题标题】:XSLT for converting XML nodename into a node valueXSLT 用于将 XML 节点名转换为节点值
【发布时间】:2014-07-16 05:46:42
【问题描述】:

我对 XSLT 很陌生,正在努力完成以下工作。我试图通过将节点名称添加为附加节点来减少 XML 文档中的层次结构数量。我无法编写正确的 XSLT。另外,有没有其他方法可以实现这一点(没有 XSLT,任何工具?)?

感谢任何帮助。谢谢。

输入 XML:

    <Rates>
    <Rate1>
        <Current>
            <onsite>100</onsite>
            <net>100</net>
            <gross>100</gross>
        </Current>
        <Past>
            <onsite>100</onsite>
            <net>100</net>
            <gross>100</gross>
        </Past>
    </Rate1>
    <Rate2>
        <Current>
            <onsite>2100</onsite>
            <net>2100</net>
            <gross>2100</gross>
        </Current>
        <Past>
            <onsite>2100</onsite>
            <net>2200</net>
            <gross>1200</gross>
        </Past>
    </Rate2>
</Rates>

预期输出:

<Rates>
    <Rate>
        <RateType>Rate1</RateType>
        <RateHistory>Current</RateHistory>
        <onsite>100</onsite>
        <net>100</net>
        <gross>100</gross>
    </Rate>
    <Rate>
        <RateType>Rate1</RateType>
        <RateHistory>Past</RateHistory>
        <onsite>100</onsite>
        <net>100</net>
        <gross>100</gross>
    </Rate>
    <Rate>
        <RateType>Rate2</RateType>
        <RateHistory>Current</RateHistory>
        <onsite>2100</onsite>
        <net>2100</net>
        <gross>2100</gross>
    </Rate>
    <Rate>
        <RateType>Rate2</RateType>
        <RateHistory>Past</RateHistory>
        <onsite>2100</onsite>
        <net>2200</net>
        <gross>1200</gross>
    </Rate>
</Rates>

【问题讨论】:

标签: xml xslt


【解决方案1】:

您正在寻找此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:output indent="yes"/>

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

    <xsl:template match="Current|Past">
        <Rate>
            <RateType><xsl:value-of select="name(..)"/></RateType>
            <RateHistory><xsl:value-of select="name()"/></RateHistory>
            <xsl:apply-templates/>
        </Rate>
    </xsl:template>

    <xsl:template match="Rate1|Rate2">
        <xsl:apply-templates/>
    </xsl:template>

</xsl:stylesheet>

【讨论】:

  • 您假设Rate1Rate2 是唯一可能的费率类型。
  • CurrentPast 是唯一可能的RateHistory 值——尽管这似乎更有可能。
  • 谢谢乔尔。作品。此外,添加到 michael 的 cmets,如果有更多的速率类型,我假设我需要更新 template_match 并添加更多类型,或者像“Rate*”这样的东西
【解决方案2】:

假设费率类型事先知道(并且假设CurrentPast是唯一可能的RateHistory值)尝试:

<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:template match="/">
    <Rates>
        <xsl:for-each select="Rates/*/*">
            <Rate>
                <RateType><xsl:value-of select="name(..)"/></RateType>
                <RateHistory><xsl:value-of select="name()"/></RateHistory>
                <xsl:copy-of select="*"/>
            </Rate>
        </xsl:for-each>
    </Rates>
</xsl:template>

</xsl:stylesheet>

【讨论】:

  • 谢谢迈克尔,感谢您更通用的回答。赞成。
猜你喜欢
  • 1970-01-01
  • 2011-09-24
  • 2019-04-26
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多