【问题标题】:How to select node/value based on given value in xslt?如何根据 xslt 中的给定值选择节点/值?
【发布时间】:2013-02-19 11:53:58
【问题描述】:

我有这种xml

<?xml version="1.0"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Rows>
<Row>
  <Id>1</Id>
  <XColumns>
    <Name>Country</Name>
    <Value>Austria</Value>
  </XColumns>
  <XColumns>
    <Name>Region</Name>
    <Value>Europe</Value>
  </XColumns>
  <XColumns>
    <Name>Sector</Name>
    <Value>Information Technology</Value>
  </XColumns>
  <YColumns>
    <Name>Dataset 1</Name>
    <Value>14</Value>
  </YColumns>
  <YColumns>
    <Name>Dataset 2</Name>
    <Value>19</Value>
  </YColumns>
</Row>
<Row>
  <Id>2</Id>
  <XColumns>
    <Name>Country</Name>
    <Value>Bahamas</Value>
  </XColumns>
  <XColumns>
    <Name>Region</Name>
    <Value>North American</Value>
  </XColumns>
  <XColumns>
    <Name>Sector</Name>
    <Value>Information Technology</Value>
  </XColumns>
  <YColumns>
    <Name>Dataset 1</Name>
    <Value>1</Value>
  </YColumns>
  <YColumns>
    <Name>Dataset 2</Name>
    <Value>15</Value>
  </YColumns>
</Row>

我需要使用 XSLT 将其转换为以下 XML

<?xml version="1.0"?>
<data>
<categories>
 <category label="Austria"/>
 <category label="Bahamas"/>
</categories>
<dataset seriesName="DataSet 1">
 <set value="14"/>
 <set value="1"/>
</dataset>
<dataset seriesName="DataSet 2">
 <set value="19"/>
 <set value="15"/>
</dataset>

还有一件事,我有一个名为“category”的变量,如果我通过 category=Country 那么它将生成 类别标签,其中标签具有奥地利、巴哈马等国家/地区的价值。如果我通过类别 = 地区,那么它将生成类别标签,其中标签具有欧洲、北美等地区的价值。所以根据类别值我必须生成类别标签。

【问题讨论】:

  • 如果您有兴趣,我已经在我的答案中添加了一种更有效的方法

标签: xml xslt xslt-1.0


【解决方案1】:

以下代码执行您尝试实现的目标。然而,根据数据集的变化可能不是最有效的方法。

我假设 YColumns 可以以不同的顺序出现,并且我们可以在源文件中找到任意数量的数据集(不仅仅是 2 个)。如果可以消除其中一些限制,解决方案可能会更简单。

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

    <xsl:output method="xml" indent="yes" />

    <!-- Holds the category to be selected -->
    <xsl:param name="category"
               select="'Country'" />

    <!-- Process root element -->
    <xsl:template match="Data">
        <data>
            <xsl:apply-templates select="*" />
        </data>
    </xsl:template>

    <xsl:template match="Rows">
        <!-- Generate category based on parameter $category -->
        <categories>
            <xsl:apply-templates select="Row/XColumns[Name = $category]" />
        </categories>
        <!-- Generate data sets -->
        <xsl:apply-templates select="Row[1]/YColumns" />
    </xsl:template> 

    <!-- Generate category element -->  
    <xsl:template match="XColumns">
        <category label="{Value}" />
    </xsl:template>

    <!-- Generate dataset elements -->
    <xsl:template match="YColumns">
        <xsl:variable name="name" select="Name" />
        <dataset seriesName="{$name}">
            <xsl:for-each select="../../Row/YColumns[Name = $name]/Value">
                <set value="{.}" />
            </xsl:for-each>
        </dataset>
    </xsl:template>

</xsl:stylesheet>

更新:更有效的方法是使用 来索引所有 YColumn 名称。所以你必须添加

<xsl:key name="data-set" match="YColumns/Value" use="../Name" />

作为 的直接子代

并改变表达式后面的表达式

../../Row/YColumns[Name = $name]/Value

key('data-set', $name)

【讨论】:

    猜你喜欢
    • 2013-02-04
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多