我想在元素中的xls中引用外部xml
<xsl:element name="{document('mapping.xml', /)/mappings/column/[@id=name()]}" >
这可能吗?
更新
mapping.xml
<?xml version="1.0" encoding="UTF-8"?>
<mappings>
<columns>
<column id="path">path</column>
</columns>
</mappings>
样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:dms="http://www.news.at/dms">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="Mapping" select="document('mapping.xml', /)" />
<xsl:template match="/">
<xsl:element name="document">
<xsl:for-each select="document/*">
<xsl:element name=
"{$Mapping/mappings/columns/column[@id = name(current())]}" />
<xsl:element name="item" >
<xsl:attribute name="id">
<xsl:if test="not($Mapping/mappings/columns/column[@id= name(current())])">
<xsl:message>Markup Error: no id attribute in <xsl:value-of select="name(current())" /></xsl:message>
</xsl:if>
<xsl:value-of select="$Mapping/mappings/columns/column[@id= name(current())]" /></xsl:attribute>
<xsl:value-of select="text()" />
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
input.xml中
<?xml version="1.0" encoding="UTF-8" ?>
<document>
<path>sdfsdfsdf</path>
</document>
谢谢!
答案 0 :(得分:1)
是的,绝对的。但是,像这样:
<xsl:element name="{normalize-space(
document('mapping.xml', /)/mappings/column[@id=name(current())]
)}" >
简单英语:这将选择<column>
中/mappings
等于XSLT中当前元素名称的任何@id
。此列的文字值将通过normalize-space()
进行修整,并成为新的<xsl:element>
名称。
(请注意,comumn[@id=name()]
表示“@id
等于其名称的任何列”,因此仅匹配<column id="column">
。current()
函数是必需的做你想做的事。)
但是,首先将文档保存到全局变量中会有所帮助:
<!-- at the <xsl:stylesheet> level... -->
<xsl:variable name="mappings"
select="document('mapping.xml', /)/mappings/column"
/>
<!-- later, anywhere... -->
<xsl:element name="{ normalize-space($mappings[@id=name(current())]) }" >
答案 1 :(得分:1)
我想引用外部xml 元素中的xls
<xsl:element name= "{document('mapping.xml', /)/mappings/column/[@id=name()]}" >
是的,name
指令的<xsl:element>
属性允许AVT(属性 - 值 - 模板s )
提供的代码存在许多问题:
您提供的代码中存在明显的语法错误:
document('mapping.xml', /)/mappings/column/[@id=name()]
不是语法上合法的XPath表达式。最后一个位置步骤缺少节点测试,只有一个谓词。
0.2。 上述表达式中没有任何内容与原始XML文档中的当前节点相关。我猜,谓词
[@id=name()]
实际上应该是这样的:
[@id=name(current())]
所以,我的猜测是你可能想要:
<xsl:element name=
"{document('mapping.xml', /)/mappings/column[@id=name(current())]}" >
还有一个额外的第三个问题:(在OP的评论中确认是真正的问题):
上面name
属性中指定为AVT的表达式可能具有不是语法上合法的QName的字符串值。 sych非法值的示例:123
或A B
在这种情况下,有不同的可能解决方案:
...
concat(
translate(substring(yourExpression,1,1),
$illegalFirstCharacters,
'________________'),
translate(substring(yourExpression,2),
$illegalCharacters,
'________________')
)
其中$illegalFirstCharacters
是一个变量,定义为包含可能作为第一个字符出现且不允许作为QName的第一个字符的所有可能字符
和$illegalCharacters
是一个变量,定义为包含可能出现在第一个字符之后的所有可能字符,并且在第一个字符之后不允许出现在QName中。
基本上,$illegalFirstCharacters
是$illegalCharacters
和字符串"0123456789"
的串联。
上面translate()
的最后一个参数必须足够长,以便为每个可能的非法字符容纳一个_
。
使用正则表达式在XPath 2.0(XSLT 2.0)中可以更容易地表达到有效QName的转换。
当然,这个解决方案应该谨慎行事,因为根据实际数据,可能会将包含非法QNAme字符的两个不同值转换为相同的QName。