Xml 如何在xslt中使用按位或?
下面的代码包含3个变量,这些变量的值依赖于xmlXml 如何在xslt中使用按位或?,xml,xslt,Xml,Xslt,下面的代码包含3个变量,这些变量的值依赖于xml <?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:date="java.
<?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:date="java.util.Date"
xmlns:vector="java.util.Vector"
xmlns:math="java.lang.Math"
xmlns:int="java.lang.Integer"
xmlns:saxon="http://saxon.sf.net/"
extension-element-prefixes="date vector math int saxon">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="var1">
code to generate the value
</xsl:variable>
<xsl:variable name="var2">
code to generate the value
</xsl:variable>
<xsl:variable name="var3">
code to generate the value
</xsl:variable>
生成值的代码
生成值的代码
生成值的代码
问题是,我必须为另一个变量组合这些值:
<xsl:variable name="var4">
value = var1 | var2 | var3
</xsl:variable>
值=var1 | var2 | var3
有没有一种优雅的方法?
我已经看过答案了,但没发现有用
我想到的唯一解决办法是
如果您使用的是Saxon 9的商业版,那么您可以调用Java并使用
BigInteger
类。下面是一个用于Saxon 9.6 PE或EE的示例,它利用该类和XSLT 3.0来实现两个xs:integer
值和xs:integer
值序列的按位或和和:
<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"
xmlns:bigint="java:java.math.BigInteger"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs math bigint mf"
version="3.0">
<xsl:param name="integer-seq1" as="xs:integer*" select="1, 2, 4, 16"/>
<xsl:function name="mf:or" as="xs:integer">
<xsl:param name="i1" as="xs:integer"/>
<xsl:param name="i2" as="xs:integer"/>
<xsl:sequence select="bigint:or(bigint:new(string($i1)), bigint:new(string($i2)))"/>
</xsl:function>
<xsl:function name="mf:or" as="xs:integer">
<xsl:param name="integers" as="xs:integer+"/>
<xsl:sequence select="fold-left(
$integers[position() gt 1],
$integers[1],
mf:or#2
)"/>
</xsl:function>
<xsl:function name="mf:and" as="xs:integer">
<xsl:param name="i1" as="xs:integer"/>
<xsl:param name="i2" as="xs:integer"/>
<xsl:sequence select="bigint:and(bigint:new(string($i1)), bigint:new(string($i2)))"/>
</xsl:function>
<xsl:function name="mf:and" as="xs:integer">
<xsl:param name="integers" as="xs:integer+"/>
<xsl:sequence select="fold-left(
$integers[position() gt 1],
$integers[1],
mf:and#2
)"/>
</xsl:function>
<xsl:template name="main">
<xsl:value-of select="mf:or(1, 16), mf:and(1, 16), mf:or($integer-seq1), mf:and($integer-seq1), ' '"/>
</xsl:template>
</xsl:stylesheet>
对于早期版本的Saxon,您不能对序列使用基于的左折叠解决方案,但两个参数版本应该可以工作。由于math:pow
返回一个xs:double
,在尝试使用函数之前,您需要先转换为整数。如果您使用Saxon 9的商业版,那么您可以调用Java并使用biginger
类。下面是一个用于Saxon 9.6 PE或EE的示例,它利用该类和XSLT 3.0来实现两个xs:integer
值和xs:integer
值序列的按位或和和:
<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"
xmlns:bigint="java:java.math.BigInteger"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs math bigint mf"
version="3.0">
<xsl:param name="integer-seq1" as="xs:integer*" select="1, 2, 4, 16"/>
<xsl:function name="mf:or" as="xs:integer">
<xsl:param name="i1" as="xs:integer"/>
<xsl:param name="i2" as="xs:integer"/>
<xsl:sequence select="bigint:or(bigint:new(string($i1)), bigint:new(string($i2)))"/>
</xsl:function>
<xsl:function name="mf:or" as="xs:integer">
<xsl:param name="integers" as="xs:integer+"/>
<xsl:sequence select="fold-left(
$integers[position() gt 1],
$integers[1],
mf:or#2
)"/>
</xsl:function>
<xsl:function name="mf:and" as="xs:integer">
<xsl:param name="i1" as="xs:integer"/>
<xsl:param name="i2" as="xs:integer"/>
<xsl:sequence select="bigint:and(bigint:new(string($i1)), bigint:new(string($i2)))"/>
</xsl:function>
<xsl:function name="mf:and" as="xs:integer">
<xsl:param name="integers" as="xs:integer+"/>
<xsl:sequence select="fold-left(
$integers[position() gt 1],
$integers[1],
mf:and#2
)"/>
</xsl:function>
<xsl:template name="main">
<xsl:value-of select="mf:or(1, 16), mf:and(1, 16), mf:or($integer-seq1), mf:and($integer-seq1), ' '"/>
</xsl:template>
</xsl:stylesheet>
对于早期版本的Saxon,您不能对序列使用基于的左折叠解决方案,但两个参数版本应该可以工作。由于math:pow
返回一个xs:double
,在尝试使用函数之前,您需要先强制转换为整数。以下是XSLT 1.0使用递归模板实现的按位或按十进制参数:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="n" select="49" />
<xsl:variable name="m" select="50" />
<xsl:template match="/">
<output>
<xsl:call-template name="bitwise-or">
<xsl:with-param name="n" select="$n"/>
<xsl:with-param name="m" select="$m"/>
</xsl:call-template>
</output>
</xsl:template>
<xsl:template name="bitwise-or">
<xsl:param name="n"/>
<xsl:param name="m"/>
<xsl:param name="power" select="1"/>
<xsl:param name="value" select="0"/>
<xsl:variable name="bit" select="$n mod 2 or $m mod 2"/>
<xsl:variable name="nextN" select="floor($n div 2)"/>
<xsl:variable name="nextM" select="floor($m div 2)"/>
<xsl:variable name="result" select="$value + $bit * $power"/>
<xsl:choose>
<xsl:when test="$nextN or $nextM">
<xsl:call-template name="bitwise-or">
<xsl:with-param name="n" select="$nextN"/>
<xsl:with-param name="m" select="$nextM"/>
<xsl:with-param name="power" select="2 * $power"/>
<xsl:with-param name="value" select="$result"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$result" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
给定示例的结果:
<?xml version="1.0" encoding="UTF-8"?>
<output>51</output>
51
下面是一个使用递归模板的按位或按十进制参数的XSLT 1.0实现:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="n" select="49" />
<xsl:variable name="m" select="50" />
<xsl:template match="/">
<output>
<xsl:call-template name="bitwise-or">
<xsl:with-param name="n" select="$n"/>
<xsl:with-param name="m" select="$m"/>
</xsl:call-template>
</output>
</xsl:template>
<xsl:template name="bitwise-or">
<xsl:param name="n"/>
<xsl:param name="m"/>
<xsl:param name="power" select="1"/>
<xsl:param name="value" select="0"/>
<xsl:variable name="bit" select="$n mod 2 or $m mod 2"/>
<xsl:variable name="nextN" select="floor($n div 2)"/>
<xsl:variable name="nextM" select="floor($m div 2)"/>
<xsl:variable name="result" select="$value + $bit * $power"/>
<xsl:choose>
<xsl:when test="$nextN or $nextM">
<xsl:call-template name="bitwise-or">
<xsl:with-param name="n" select="$nextN"/>
<xsl:with-param name="m" select="$nextM"/>
<xsl:with-param name="power" select="2 * $power"/>
<xsl:with-param name="value" select="$result"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$result" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
给定示例的结果:
<?xml version="1.0" encoding="UTF-8"?>
<output>51</output>
51
Saxon 9.6(PE或更高版本)实现了EXPath二进制模块
这提供了对base64二进制值的诸如bin:or、bin:and、bin:xor之类的操作,以及将整数转换为base64二进制值的诸如bin:pack integer之类的操作。Saxon 9.6(PE或更高版本)实现了EXPath二进制模块
这提供了对base64二进制值的诸如bin:or、bin:and、bin:xor之类的操作,以及将整数转换为base64二进制值的诸如bin:pack integer之类的操作。您的变量包含哪些类型的值?你使用哪种版本的萨克森?您是否检查过是否可以使用Java扩展函数对数字执行按位操作?变量包含8位值,我不知道在哪里检查Saxon版本,也不知道如何使用Java扩展函数。您可以向我们展示定义变量值的代码吗?或者至少告诉我们变量在XSLT/XPath类型系统中的类型。至于检查Saxon版本,如果您从命令行运行Saxon,然后使用-t
选项,它将从Saxonica
输出类似Saxon PE 9.6.0.1J的详细信息。这看起来像是
我有更多的文档,我想知道是否可以使用Java.math.bigInteger您的变量包含哪些值?你使用哪种版本的萨克森?您是否检查过是否可以使用Java扩展函数对数字执行按位操作?变量包含8位值,我不知道在哪里检查Saxon版本,也不知道如何使用Java扩展函数。您可以向我们展示定义变量值的代码吗?或者至少告诉我们变量在XSLT/XPath类型系统中的类型。至于检查Saxon版本,如果您从命令行运行Saxon,然后使用-t
选项,它将输出Saxonica的Saxon PE 9.6.0.1J之类的详细信息。这看起来像是
我已经记录了更多,我想知道是否可以使用Java.math.bigInteger非常感谢您的帮助!我在#
字符处遇到一个错误,但是我可以用
来管理。正如我所说的,使用左折的函数定义(以及函数引用mf:or#2
)是XSLT/XPath 3.0,只有Saxon 9.6 PE或EE支持。非常感谢您的帮助!我在#
字符处出错,但我可以使用
进行处理。正如我所说,函数定义使用向左折叠(函数引用mf:or#2
)XSLT/XPath 3.0是否仅由Saxon 9.6 PE或EE支持。感谢您的帮助,但使用java方法更安全、更容易。@AlexandruCimpanu更安全?感谢您的帮助,但使用java方法更安全、更容易。@AlexandruCimpanu更安全?