XML元素的子元素的通用处理

时间:2012-09-20 23:04:52

标签: xml xslt

假设我们有以下XML ...

<FruitBasket>
    <Basket>
        <Apple>1</Apple>
        <Banana>2</Banana>
        <Orange>3</Orange>
    </Basket>
    <Basket>
        <Avocado>1</Avocado>
        <Lemon>2</Lemon>
    </Basket>
</FruitBasket>

使用XSLT我将如何生成以下转换?

<BasketContents>
    <Content>
        <FruitName>Apple</FruitName>
        <FruitAmount>1</FruitAmount>
        <FruitName>Banana</FruitName>
        <FruitAmount>2</FruitAmount>
        <FruitName>Orange</FruitName>
        <FruitAmount>3</FruitAmount>
    </Content>
    <Content>
        <FruitName>Avocado</FruitName>
        <FruitAmount>1</FruitAmount>
        <FruitName>Lemon</FruitName>
        <FruitAmount>2</FruitAmount>
    </Content>
</BasketContents>

我需要这样做,一般不知道篮子里有什么类型的水果xslt必须处理“篮子”的任何子元素。例如,我不知道篮子里是否含有苹果或鳄梨,我也不知道篮子里有多少种水果。

基本上,这分解为需要知道如何调用子元素的名称,所以从XML的<Basket>元素,我可以应用模板来获取它的未知子元素的名称。

对不起,如果这个比喻更容易让人感到困惑。

1 个答案:

答案 0 :(得分:2)

如果水果名称不重复(或者重复的水果名称是产生两个FruitNameFruitAmount对),那么这样的东西应该做你需要的:

<xsl:template match="/FruitBasket">
  <BasketContents>
    <xsl:apply-templates/>
  </BasketContents>
</xsl:template>

<xsl:template match="Basket">
  <Content>
    <xsl:apply-templates/>
  </Content>
</xsl:template>

<xsl:template match="Basket/*">
  <FruitName>
    <xsl:value-of select="name()"/>
  </FruitName>
  <FruitAmount>
    <xsl:value-of select="."/>
  </FruitAmount>
</xsl:template>

如果您需要检测给定水果的多次出现并将其内容相加,那么您将需要阅读有关XSLT上良好参考源的分组。在XSLT 1.0中,索引中要查找的关键字是“Muenchian grouping”。在XSLT 2.0中,分组更简单(有分组构造)。