通过比较两个值来创建链接

时间:2018-09-27 12:01:41

标签: html xml xslt xpath

我尝试将问题分解为最简单的示例,希望您能理解。 所以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'与内部的StrawberryID进行比较。

1 个答案:

答案 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。