在节点属性中使用变量

时间:2019-01-06 07:37:09

标签: xpath xslt-1.0

我正在编写XSL模板。我没有得到如何为XSL文件中的自定义属性指定变量。

我正在XSL中尝试此代码:

setupArray()

预期结果是

if let filepath = Bundle.main.path(forResource: files[index], ofType: "txt")

我收到此错误:

  

无法使用提供的XML / XSL输入生成XML文档。 org.xml.sax.SAXParseException; lineNumber:18; columnNumber:24;元素类型“ sourceId”后必须跟属性规范““>”或“ />”

问题是我串联的方式是错误的。有什么帮助吗?

2 个答案:

答案 0 :(得分:0)

我想你是说:

<frequency myAttr="ABC{$var1}" >  

这会将文字字符串"ABC"$var1变量的内容连接在一起-参见:Attribute Value Templates

请注意,填充变量的方式表明在源XML中有一个名为DEF的元素。仅当此元素的字符串值为"DEF"时,才能获得预期的结果。

答案 1 :(得分:0)

XSL是XML格式的声明性语言。 XSLT文件必须是格式正确的XML。

您尝试的内容看起来像是具有命令式语言的编程知识,您可以在其中编写类似"ABC" + $var1的表达式。但是,这违反了XSL中的XML格式规则。元素遵循模式<elementname attribute1="value1" attributeN="valueN">...</elementname>。在您的代码中,将+$var1放在myAttr属性的末尾,该属性在第二个引号结束-这是无效的:<frequency myAttr="ABC"+$var1 >

<frequency myAttr="ABC+$var1">将导致文字属性值ABC+$var1,这不是您想要的。如果您尝试将XPath语法用作属性值,将concat('ABC', $var1)用作<frequency myAttr="concat('ABC', $var1)">中的字符串,也会发生这种情况。

您可以按照michael.hor257k的建议使用“属性值模板”语法,这实际上意味着将XPath表达式包装在属性值字符串内的花括号中。

另一种方法是不在代码中将元素写为原义,而是声明它:

<xsl:variable name="var1" select="'DEF'"/>
<xsl:element name="frequency">
  <xsl:attribute name="myAttr">
    <xsl:value-of select="concat('ABC', $var1)"/>
  </xsl:attribute>
</xsl:element>

请注意,我已更正了变量定义:在select属性中,如果应该将DEF放在字符串中,例如select="'DEF'",则必须将其放在单引号中。如果没有单引号,则可以定义变量以引用源XML中的<DEF>元素。

select的{​​{1}}属性中,我使用了XPath函数<xsl:value-of>来连接字符串concat()和变量'ABC'的内容。在这里不能使用属性值模板语法:$var1将导致字符串select="'ABC{$var1}'"

上述示例的一种变体是对字符串ABC{$var1}<xsl:text>使用ABC来输出<xsl:value-of>的内容:

$var1

因此,有三种解决方案,一种是简洁的,另一种是两种声明性的。您选择哪一个取决于您。输入速度最快的肯定是第一个:

<xsl:variable name="var1" select="'DEF'"/>
<xsl:element name="frequency">
  <xsl:attribute name="myAttr">
    <xsl:text>ABC</xsl:text>
    <xsl:value-of select="$var1"/>
  </xsl:attribute>
</xsl:element>

...但是您还应该注意两种声明性方法来获得相同的结果并了解它们的工作原理。