我尝试将问题分解为最简单的示例,希望您能理解。 所以XML看起来像这样:
<!-- FruitsID12345 is the id I want -->
<Fruits id="system://data/Fruits/FruitsID12345/?language=en-GB" majorVersion="1">
<Header> A header - not important </Header>
<!-- interesting is 'Strawberry' and the 'id' behind it -->
<Strawberry id="system://data/Strawberry/StrawberryID12345/?language=en-GB" version="2">
<Description> Some text - not important </Description>
<Content> Can be filled with content </Content>
<Strawberry>
</Fruits>
<!-- There can be more Stawberries just with other IDs -->
<MuchMoreFruits>.....</MuchMoreFruits>
<Lemon>
<!-- 'targetid' and 'href' are the same -->
<Text> Click the following link:
<Link targetid="system://data/Strawberry/StrawberryID12345/"
version="2" href="system://data/Strawberry/StrawberryID12345/">Click me
</Link>
</Text>
</Lemon>
我需要什么:
{id from Fruits} {major-version from Fruits} {object-type from Fruits} {component-information}
component-information如下:
{id from Strawberry} {version from Strawberry} {object-type from Strawberry}
因此解决方案应如下所示:
<a href="" my.id="FruitsID12345" my.majorVersion="1" my.type="Fruits"
my.component="StrawberryID12345_2_Strawberry">Click me</a>
到目前为止,我已经完成了看起来像这样的组件部分:
<xsl:template match="Link">
<a>
<!-- think I can put that part in <a> -->
<xsl:attribute name="href"/>
<xsl:attribute name="my.component>
<!-- template to get the id -->
<!-- substring-before(substring-after(substring-after(., 'data/'), '/'), '/') -->
<xsl:apply-templates select="@targetid"/>
<xsl:text>_</xsl:text>
<xsl:value-of select="@version"/>
<xsl:text>_</xsl:text>
<!-- template to get the object-type -->
<!-- substring-before(substring-after(@targetid, 'data/'), '/') -->
<xsl:call-template name="objecttype"/>
</xsl:attribute>
</a>
<水果>中的信息。我需要以某种方式将中的'StrawberryID'与
答案 0 :(得分:1)
您可以定义一个键,但不确定元素名称的可变性,下面我为父元素和子元素都具有id
属性的根元素的任何孙元素定义了它,而使用XSLT 1则是一堆无法理解的嵌套substring-before/substring-after
调用,它们会提取内容:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="fruit-ref" match="/*/*[@id]/*[@id]" use="substring-before(@id, '?')"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Text/Link[@href]">
<xsl:variable name="referenced-fruit" select="key('fruit-ref', @href)"/>
<xsl:variable name="parent-fruit" select="$referenced-fruit/.."/>
<a href="" my.id="{substring-before(substring-after(substring-after(substring-after(substring-after($parent-fruit/@id, '/'), '/'), '/'), '/'), '/')}"
my.majorVersion="{$parent-fruit/@majorVersion}"
my.type="{local-name($parent-fruit)}"
my.component="{substring-before(substring-after(substring-after(substring-after(substring-after($referenced-fruit/@id, '/'), '/'), '/'), '/'), '/')}_{$referenced-fruit/@version}_{local-name($referenced-fruit)}">Click me</a>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bdxtqK给出了想要的结果<a href="" my.id="FruitsID12345" my.majorVersion="1" my.type="Fruits" my.component="StrawberryID12345_2_Strawberry">Click me</a>
,因此希望能对您有所帮助。我不确定所使用的键表达式use="substring-before(@id, '?')
是否足够精确,但是当然也可以将其转换为更特定(且可读性更差)的嵌套字符串函数调用mess。