我有一个XML文件:
<?xml version="1.0" standalone="yes"?>
<Questionnaire>
<Temp_GridTypeTable_6>
<Column2>Select Yes/No</Column2>
</Temp_GridTypeTable_6>
<Temp_GridTypeTable_1>
<Column2>Rank 1,2,3</Column2>
</Temp_GridTypeTable_1>
<Temp_GridTypeTable_1>
<Column1>I needed the income</Column1>
<Column2>Why did you take a job on this project?</Column2>
</Temp_GridTypeTable_1>
<Temp_GridTypeTable_1>
<Column1>Other</Column1>
<Column2></Column2>
</Temp_GridTypeTable_1>
<Temp_GridTypeTable_2>
<Column2>Select "Yes/No"</Column2>
</Temp_GridTypeTable_2>
<Temp_GridTypeTable_2>
<Column1>No jobs</Column1>
<Column2>344</Column2>
</Temp_GridTypeTable_2>
<Temp_GridTypeTable_3>
<Column2>Input</Column2>
</Temp_GridTypeTable_3>
<Temp_GridTypeTable_3>
<Column1>Unit</Column1>
<Column2>123</Column2>
</Temp_GridTypeTable_3>
</Questionnaire>
我想访问
<xsl:for-each select="Questionnaire/concat('Temp_GridTypeTablenode_',"1"))>
但这句话不起作用。
答案 0 :(得分:11)
这是如何不使用XML的一个例子。 “Temp_GridTypeTable”和“Column”数字是数据,而不是结构,它们不应包含在元素名称中。所以为什么你不使用不那么痛苦的东西,比如说:
<Questionnaire>
<Temp_GridTypeTable type="6">
<Column num="2">Select Yes/No</Column>
</Temp_GridTypeTable>
<Temp_GridTypeTable type="1">
<!-- ... -->
<Temp_GridTypeTable>
<!-- ... -->
</Questionnaire>
话虽如此,对于你目前的情况,这是必要的:
<xsl:for-each select="Questionnaire/*[
local-name()
=
concat('Temp_GridTypeTable_', '1')
]">
对于输入的“较少痛苦”版本,这是必需的:
<xsl:for-each select="Questionnaire/Temp_GridTypeTable[@type = 1]">
尽管第二个表达式更简单,更直接,但它的表现也会好得多。如果您可以提供帮助,我建议您更改输入XML。
编辑:继续在评论中展开自己的论点,我试着强调local-name()
和name()
XPath函数之间的区别,以及差异的重要性:
| XML has namespaces | XML has no namespaces ----------------------------+---------------------+----------------------- I care about namespaces | use `name()` | use either function | | don't care about namespaces | use `local-name()` | use either function
通常:如果你属于“不关心命名空间”组(大多数XML新手或临时XML用户都这样做),那么只使用local-name()
就可以了(有时甚至是有益的)。但是,当您获得的结果和您期望的结果开始分歧时,请准备好了解XML命名空间。此时您不再属于该组。
如果您属于“我关心命名空间”组,您无论如何都不需要此建议。 ; - )
答案 1 :(得分:2)
使用:
<强> Questionnaire/*[name() = concat('', $vSuffix)]
强>
变量$vSuffix
包含静态未知字符串 - 在本例中为“1”。
在Tomalak的答案中使用local-name()
是不必要的长且不精确的,因为在一般情况下它允许具有各种(可能不需要的和意外的)名称的元素被选中,例如:
OhMy:Temp_GridTypeTable_1
Different:Temp_GridTypeTable_1
UnWanted:Temp_GridTypeTable_1
答案 2 :(得分:1)
您无法在运行时使用纯XSLT将字符串计算为XPath表达式。
您需要一个可以在运行时评估xpath表达式的扩展函数。例如,请参阅EXSLT project。
在我的系统上,使用xsltproc
,我可以完成你想要的任务:
<!-- load the saxon extensions -->
<xsl:stylesheet version="1.0" xmlns:xx="http://icl.com/saxon"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
...
...
<xsl:for-each
select="xx:evaluate(concat('Questionnaire/Temp_GridTypeTable_', '1'))">
在这里,我使用saxon扩展库中的evaluate函数。 EXSLT的评估函数应该以相同的方式工作。
XSLT处理器/库必须内置某种evaluate
函数。请参阅库的文档。