我正在尝试使用apply-templates从多个类似的父节点迭代特定的子节点。示例如下:
<test_report
xmlns:gml="http://www.opengis.net/gml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<countries>
<country name='sample1'>
<education>
<men>
<literacyRates>25,36,43</literacyRates>
</men>
</education>
</country>
<country name='sample2'>
<education>
<men>
<literacyRates>45,46,55,56</literacyRates>
</men>
</education>
</country>
</countries>
现在,我想在所有属于countries元素的literacyRates元素上应用模板。我尝试了下面的XSL:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="countries">
<xsl:call-template name="countries" />
</xsl:template>
<xsl:template name="countries" match="literacyRate">
<xsl:call-template name="testoutput"><xsl:with-param name="list" select="." /> </xsl:call-template>
]
</xsl:template>
<xsl:template name="testoutput">
<xsl:param name="list" select="."/>
list=<xsl:value-of select="$list" />
</xsl:template>
我原本期望以list=
开头的输出行出现两次,因为我们有两个literacyRate元素匹配,但事实并非如此。需要一些帮助。
答案 0 :(得分:3)
尝试以下脚本:
curl -H "Content-Type: application/json" -X POST -d '"{\"id\":\"2773\",\"countryCode\":\"US\",\"orderAmt\":\"100\"}"' http://localhost:9090
curl -H "Content-Type: application/json" -X POST -d '"{\"id\":\"2774\",\"countryCode\":\"CA\",\"orderAmt\":\"125\"}"' http://localhost:9090
curl -H "Content-Type: application/json" -X POST -d '"{\"id\":\"2775\",\"countryCode\":\"US\",\"orderAmt\":\"110\"}"' http://localhost:9090
或另一种解决方案,如果真的需要使用<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="country//literacyRates">
<xsl:text>list=</xsl:text>
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
:
apply-templates
答案 1 :(得分:1)
您的XSL存在许多问题。
您使用call-template
的方式没有多大意义。使用apply-templates
会更加惯用。
您有三个模板,但实际上只在最后一个模板中执行任何操作 - 而且只输出<countries>
元素的字符串值。也可以只有一个模板:
<xsl:template match="countries">
list=<xsl:value-of select="."/>
</xsl:template>
(我假设您的第二个模板中的换行符和]
结束括号是错误的。)
您的第二个模板同时具有name
属性和match
属性。
<xsl:template name="countries" match="literacyRate">
<xsl:call-template name="testoutput"><xsl:with-param name="list" select="." /> </xsl:call-template>
]
</xsl:template>
如果您在处理流程中使用match
,apply-templates
属性只会执行任何操作。由于您只使用call-template
,match
属性不执行任何操作
此外,由于match
属性指定literacyRate
,但您的输入XML只有literacyRates
个元素,因此仍然不会执行任何操作,即使您使用{ {1}}早些时候。
您希望每个apply-templates
元素都有一个list=
行。要将此输出生成为直接文本,以下操作:
<country>
打破这种局面,我们有:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="countries">
<xsl:apply-templates select="country//literacyRates"/>
</xsl:template>
<xsl:template match="literacyRates">
<xsl:text>list=</xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
指定我们输出的是文本,而不是XML。这可能会影响输出格式,具体取决于您的XSL处理器。<xsl:output method="text"/>
防止源XML和XSL中的空格(即缩进)影响输出中的空格。<xsl:strip-space elements="*"/>
至<xsl:apply-templates select="country//literacyRates"/>
,以及具体apply-templates
仅select
个literacyRates
元素后代的元素。这假设每个country
元素只有一个 <country>
后代元素。如果有多个这样的元素,输出将变得混乱 - 每个值列表将被附加到输出字符串,可能导致输出行像<literacyRates>
(其中两个列表被一起排列,两者之间没有任何内容)
上面的文字输出有些有些混乱 - 我们不知道哪个列表属于哪个国家/地区,而list=25,36,4345,46,55,56
中的多个<literacyRates>
会产生损坏的输出。
这是生成XML的替代输出,包含更多信息。
<country>