【问题标题】:How to use evaluate如何使用评估
【发布时间】:2018-05-16 07:09:07
【问题描述】:

我目前正在查看我们有一个样式表要处理的 XML 代码。

我的代码如下所示

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-model href="register_tool/rules/rules.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>

<addrmap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="register_tool/rules/man_schema.xsd" name="di_do_1430_board" offset="0x0" lsb_size="32">

    <enum name="ch_handler_ch_type" bitfield="false">
        <element name="be" value="0" offset="0x00000000"/> 
    </enum>

    <addrmap name="be_sys" offset="0x00000000" offset_xpath="addrmap/enum/element[@name='be']/@offset" lsb_size="24">
        <ref name="be_reg_acc" path="blocks/be_reg_acc.xml" ref_name="be_reg_acc" offset="0x0" />
    </addrmap>

</addrmap>

我的样式表的一部分如下所示

<xsl:choose>
  <xsl:when test="@offset_xpath">
    <xsl:variable name="resolved_offset"><xsl:evaluate xpath="@offset_xpath"></xsl:evaluate></xsl:variable>
    <xsl:apply-templates mode="map">
      <xsl:with-param name="offset" select="rdt:all2dec($resolved_offset)"/>
    </xsl:apply-templates>
  </xsl:when>
  <xsl:otherwise>
    <xsl:apply-templates mode="map">
      <xsl:with-param name="offset" select="rdt:all2dec(@offset)"/>
    </xsl:apply-templates>
  </xsl:otherwise> 
</xsl:choose>

我试图从我的 enum(ch_handler_ch_type) 中获取值,但使用上面的表达式 xsl:evaluate 只给了我#document/fragment 我无法弄清楚如何获取特定值

我正在使用 Saxon-EE 9.8.0.8

问候

编辑

我已将 xi:include 替换为 enum 以更清楚地了解文件的外观。我的目标是 offset_xpath 所在的子 addrmap 节点,我需要更改偏移值。 enum 节点中定义的偏移值。

我已经成功地使用

从枚举中获取了值
<xsl:variable name="resolved_offset"><xsl:value-of><xsl:evaluate xpath="@offset_xpath" context-item="." as="xs:string"></xsl:evaluate></xsl:value-of></xsl:variable>

现在我只是不知道如何更改节点 addrmap 中的属性值偏移量。

我试着做一个模板

<xsl:template match="@offset[parent::addrmap]">
  <xsl:param name="resolved_offset" tunnel="yes"/>
  <xsl:attribute name="offset">
    <xsl:value-of select="$resolved_offset"/>
  </xsl:attribute>
</xsl:template>

我还可以看到它被正确调用,但是没有发生更改

【问题讨论】:

  • 请向我们展示上下文(字面意思),如果不知道上下文节点(由例如xsl:template matchxsl:for-each select 定义),我们无法确定xsl:choosexsl:evaluate 是否有意义外部代码已设置。
  • 检查xi:include 是否实际被扩展:这取决于设置正确的选项 (-xi) 和使用正确的 XML 解析器。

标签: xml saxon xslt-3.0


【解决方案1】:

一般来说,有必要为xsl:evaluate 定义context-item,如果我们假设您在内部addrmap 的上下文中拥有xsl:evaluate,那么您拥有addrmap/enum/element[@name='be']/@offset 的路径仅在以下情况下才有意义您想相对于根节点 / 评估它,因此您需要例如

<xsl:evaluate xpath="@offset_xpath" context-item="/" as="xs:string"/>

或者你需要改变路径。我已添加 as="xs:string" 以选择单个属性节点,而不是其值会导致您的 xsl:value-of 出现问题。

这里有一个更完整的xsl:evaluate例子

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template match="enum"/>

    <xsl:template match="addrmap[@offset_xpath]/ref/@offset">
        <xsl:attribute name="{name()}">
            <xsl:evaluate xpath="../../@offset_xpath" context-item="/"/>
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

它将您最新的输入样本转换为

<addrmap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="di_do_1430_board" offset="0x0" lsb_size="32">



    <addrmap name="be_sys" offset="0x00000000" offset_xpath="addrmap/enum/element[@name='be']/@offset" lsb_size="24">
        <ref name="be_reg_acc" path="blocks/be_reg_acc.xml" ref_name="be_reg_acc" offset="0x00000000"/>
    </addrmap>

</addrmap>

如您所见,addrmap 元素的ref 子元素的offset 属性已更改。

仍然无法理解您对给定路径和context-item="." 的尝试,因为我不明白为什么相对路径addrmap/enum/element[@name='be']/@offset 会选择任何东西。

在前面的示例中,不清楚rdt:all2dec 做什么或需要做什么,一般来说,我认为尝试使用xsl:choose/xsl:when 检查某个节点结构更容易通过像我所做的那样简单地编写匹配模式来处理使用match="addrmap[@offset_xpath]/ref/@offset,对于另一种情况,您可以使用例如&lt;xsl:template match="addrmap[not(@offset_xpath)]/ref/@offset"&gt;.

【讨论】:

  • rdt:all2dec 是一个内部函数,将所有值类型字符串转换为十进制数
  • 当我使用上面的代码时,除了设置属性之外,它会正确执行所有操作。我得到 无法创建其父节点是文档节点的属性节点(偏移量)。最近的元素开始标记在模块 unknown 的第 -1 行输出
  • 鉴于完整的样式表有&lt;xsl:mode on-no-match="shallow-copy"/&gt;,它负责复制所有节点,然后只需一个模板来处理属性并使用不同的价值。所以在我的测试中确实有效并且不会产生那个错误。
  • 我现在可以使用它了。不知道出了什么问题,可能是类型错误
猜你喜欢
  • 2013-05-06
  • 2016-02-26
  • 1970-01-01
  • 1970-01-01
  • 2019-11-29
  • 2013-01-07
  • 2023-03-23
  • 2021-12-01
相关资源
最近更新 更多