XSLT 2.0 3.0 for-EAK上下文错误时属性属性时

发布于 2025-02-12 05:17:31 字数 2335 浏览 2 评论 0原文

给定此XML,

<dmodule>   
      <content>     
            <warningsAndCautionsRef>
                  <warningRef id="w001" warningIdentNumber="warning-001">
                  </warningRef>
                  <warningRef id="w002" warningIdentNumber="warning-002">
                  </warningRef>
                  <cautionRef id="c001" cautionIdentNumber="caution-001">
                  </cautionRef>
                  <cautionRef id="c002" cautionIdentNumber="caution-002">
                  </cautionRef>
            </warningsAndCautionsRef>
            <faultReporting>
                  <preliminaryRqmts>
                        <reqSafety>
                              <safetyRqmts cautionRefs="c001 c002" warningRefs="w001 w002"/>
                        </reqSafety>
                  </preliminaryRqmts>
            </faultReporting>
      </content>
</dmodule>
     

我想将属性@cautionrefs(和@warningrefs),然后找到与其匹配的codiate> coce> caution> @id到令牌化值:

<xsl:template match="@cautionRefs">
    <xsl:for-each select="tokenize(.,'\s')">
      <xsl:apply-templates select="//*[@id=.]"/>
    </xsl:for-each>
</xsl:template>

但是应用程序失败:转换期间的致命错误'/'选择什么都没有选择:上下文项目不是节点。如果我不象征化并使用字符串函数,但这是不可取的,它可以工作。

所需结果: tokenize @cautionRefs =“ C001 C002”(具有多个父元素),

因此每个值都传递到&lt; cautionref&gt;模板,该模板将检索警告和警告语句,,警告语句要在pdf中显示:

<xsl:apply-templates select="//*[@id='c001']"/>
<xsl:apply-templates select="//*[@id='c002']"/> 

我尝试使用&lt; xsl:key name =“ id” match =“*”使用=“@ID”/&gt; with

<xsl:for-each select="key('id',tokenize(.,'\s'))">

with 是空白的。

上述应用程序将与此&lt; wivutionref&gt;模板匹配,该模板可以正确检索谨慎和警告语句。我只需要在@CautionRefs模板上的上下文中提供帮助:

<xsl:template match="cautionRef">
    <xsl:variable name="IdentNumber" select="@cautionIdentNumber"/>
    <xsl:apply-templates select="//cautionSpec[cautionIdent/@cautionIdentNumber=$IdentNumber]"/>
  </xsl:template>

Given this XML

<dmodule>   
      <content>     
            <warningsAndCautionsRef>
                  <warningRef id="w001" warningIdentNumber="warning-001">
                  </warningRef>
                  <warningRef id="w002" warningIdentNumber="warning-002">
                  </warningRef>
                  <cautionRef id="c001" cautionIdentNumber="caution-001">
                  </cautionRef>
                  <cautionRef id="c002" cautionIdentNumber="caution-002">
                  </cautionRef>
            </warningsAndCautionsRef>
            <faultReporting>
                  <preliminaryRqmts>
                        <reqSafety>
                              <safetyRqmts cautionRefs="c001 c002" warningRefs="w001 w002"/>
                        </reqSafety>
                  </preliminaryRqmts>
            </faultReporting>
      </content>
</dmodule>
     

I would like to tokenize the attributes @cautionRefs (and @warningRefs) and then find the cautionRef element that matches its @id to the tokenized value:

<xsl:template match="@cautionRefs">
    <xsl:for-each select="tokenize(.,'\s')">
      <xsl:apply-templates select="//*[@id=.]"/>
    </xsl:for-each>
</xsl:template>

but the apply-templates fails: Fatal error during transformation Leading '/' selects nothing: the context item is not a node. It works if I don't tokenize and use string functions instead but that is not desirable.

Desired result:
Tokenize @cautionRefs="c001 c002" (which has multiple parent elements)

So each value is passed to the <cautionRef>template that will retrieve the caution and warning statements, to be displayed in a PDF:

<xsl:apply-templates select="//*[@id='c001']"/>
<xsl:apply-templates select="//*[@id='c002']"/> 

I tried using <xsl:key name="id" match="*" use="@id"/> with

<xsl:for-each select="key('id',tokenize(.,'\s'))">

but the for-each is blank.

The above apply-templates will match with this <cautionRef> template, which retrieves the caution and warning statements correctly. I just need help with the context of the @cautionRefs template:

<xsl:template match="cautionRef">
    <xsl:variable name="IdentNumber" select="@cautionIdentNumber"/>
    <xsl:apply-templates select="//cautionSpec[cautionIdent/@cautionIdentNumber=$IdentNumber]"/>
  </xsl:template>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最初的梦 2025-02-19 05:17:31

您可以使用变量并将其用于上下文:

<xsl:template match="@cautionRefs|@warningRefs">
    <xsl:variable name="ctx" select="/"/>
    <xsl:for-each select="tokenize(.,'\s')">
      <xsl:apply-templates select="$ctx//*[@id=.]"/>
    </xsl:for-each>
</xsl:template>

但是我会使用,就像您暗示的那样(根据注释更新为“包含上下文”)...

<xsl:key name="by_id" match="*[@id]" use="@id"/>

<xsl:variable name="root" select="/"/>

<xsl:template match="@cautionRefs|@warningRefs">
    <xsl:for-each select="tokenize(.,'\s')">
        <xsl:apply-templates select="key('by_id',.,$root)"/>
    </xsl:for-each>
</xsl:template>

You could use a variable and use that for context:

<xsl:template match="@cautionRefs|@warningRefs">
    <xsl:variable name="ctx" select="/"/>
    <xsl:for-each select="tokenize(.,'\s')">
      <xsl:apply-templates select="$ctx//*[@id=.]"/>
    </xsl:for-each>
</xsl:template>

but I would use a key like you hinted at (updated to include context based on comments)...

<xsl:key name="by_id" match="*[@id]" use="@id"/>

<xsl:variable name="root" select="/"/>

<xsl:template match="@cautionRefs|@warningRefs">
    <xsl:for-each select="tokenize(.,'\s')">
        <xsl:apply-templates select="key('by_id',.,$root)"/>
    </xsl:for-each>
</xsl:template>
独夜无伴 2025-02-19 05:17:31

这是一个完整的示例。 NB最好在实际问题中拥有这种细节。即示例输入文件,XSLT和输出,以及您想要的输出的示例。

输入:

<test>
  <safetyRqmts cautionRefs="c001 c002" warningRefs="w001"/>
  <cautionRef id="c001" cautionIdentNumber="caution-001"/>
  <cautionRef id="c002" cautionIdentNumber="caution-001"/>
</test>   

样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">
  
<xsl:template match="*|@*">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<xsl:key name="by_id" match="*[@id]" use="@id"/>

<xsl:template match="@cautionRefs|@warningRefs">
    <xsl:apply-templates select="key('by_id', tokenize(.))"/>
</xsl:template>

</xsl:stylesheet>

输出:

<test>
  <safetyRqmts><cautionRef id="c001" cautionIdentNumber="caution-001"/><cautionRef id="c002" cautionIdentNumber="caution-001"/></safetyRqmts>
  <cautionRef id="c001" cautionIdentNumber="caution-001"/>
  <cautionRef id="c002" cautionIdentNumber="caution-001"/>
</test>

Here's a full working example. NB it's best to have this level of detail in the actual question; i.e. a sample input file, the XSLT, and output, along with an example of what you want the output to look like.

Input:

<test>
  <safetyRqmts cautionRefs="c001 c002" warningRefs="w001"/>
  <cautionRef id="c001" cautionIdentNumber="caution-001"/>
  <cautionRef id="c002" cautionIdentNumber="caution-001"/>
</test>   

Stylesheet:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">
  
<xsl:template match="*|@*">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<xsl:key name="by_id" match="*[@id]" use="@id"/>

<xsl:template match="@cautionRefs|@warningRefs">
    <xsl:apply-templates select="key('by_id', tokenize(.))"/>
</xsl:template>

</xsl:stylesheet>

Output:

<test>
  <safetyRqmts><cautionRef id="c001" cautionIdentNumber="caution-001"/><cautionRef id="c002" cautionIdentNumber="caution-001"/></safetyRqmts>
  <cautionRef id="c001" cautionIdentNumber="caution-001"/>
  <cautionRef id="c002" cautionIdentNumber="caution-001"/>
</test>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文