在XSLT中选择两个属性

时间:2017-03-17 18:24:31

标签: xml xslt

我想使用XSLT从XML中选择'language'和'food',其中包含以下元素:

  <item id="1">
    <language>Spanish</language>
    <food>Paella</food>
    <score>3.5</score>
  </item>
  <item id="2">
    <language>Italian</language>
    <food>Spagetthi</food>
    <score>3.5</score>
  </item>

我试过以下但是它似乎不起作用:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>

  <xsl:template match="language|food">
    <xsl:apply-templates/>
    <xsl:value-of select="language, ';')"/>
    <xsl:value-of select="food, ';')"/>
  </xsl:template>

</xsl:stylesheet>

我正在寻找的输出是这样的: 西班牙语;饭,意大利; Spagetthi;

2 个答案:

答案 0 :(得分:2)

假设您的输入实际上是这样的:

<强> XML

final JsonGenerator generator = factory.createGenerator(output, JsonEncoding.UTF8);
generator.writeStartArray();
for (String arg: argsList) {
    generator.writeString(arg);
}
generator.writeEndArray();

你可以使用:

XSLT 1.0

<world>
  <item id="1">
    <language>Spanish</language>
    <food>Paella</food>
    <score>3.5</score>
  </item>
 <item id="2">
    <language>Italian</language>
    <food>Spagetthi</food>
    <score>3.5</score>
  </item>
</world>

或者,如果您愿意:

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

<xsl:template match="/world">
    <xsl:for-each select="item">
        <xsl:value-of select="language"/>
        <xsl:text>;</xsl:text>
        <xsl:value-of select="food"/>
        <xsl:text>;</xsl:text>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

得到:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>

<xsl:template match="item">
    <xsl:value-of select="language"/>
    <xsl:text>;</xsl:text>
    <xsl:value-of select="food"/>
    <xsl:text>;</xsl:text>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:2)

@ michael.hor257k非常友好地提供了工作代码,但是他并没有告诉你为什么你的尝试被打破了,所以我担心这可能不会让你更好地理解这些概念。让我们来看看你的尝试:

  <xsl:template match="language|food">
    <xsl:apply-templates/>
    <xsl:value-of select="language, ';')"/>
    <xsl:value-of select="food, ';')"/>
  </xsl:template>

这有几个原因无法奏效。

首先,您需要修复xsl:value-of指令中缺少的括号。如果要输出语言元素后跟分号的值,可以采用多种方法:

<xsl:value-of select="concat(language, ';')"/>

<xsl:value-of select="language"/>
<xsl:text>;</xsl:text>

或在XSLT 2.0(或更高版本)中

<xsl:value-of select="language, ';'"/>

第二点:像select="language"这样的表达式是select="child::language"的缩写 - 它选择的语言元素是当前(或“上下文”)节点的子元素。在xsl:template中,上下文节点是匹配模式匹配的节点。您的匹配模式为match="language|food"。这些都没有一个名为language或food的子元素,因此你的xsl:value-of指令不会选择任何内容。

第三点:您的模板规则是两次处理匹配元素的子元素。首先,它使用xsl:apply-templates来处理使用模式匹配的子项,然后使用xsl:value-of按名称显式处理它们。这两种技术都很好;同时使用它们通常会给你重复输出。