Regex 在XSLT中使用多个正则表达式:如何减少处理时间
我对编程和XSLT非常陌生:我试图改进提问和解释问题的方式,但我还有很长的路要走。对不起,如果有不清楚的地方 我需要检测XML文档中的各种字母表,看起来像这样,有更多不同的语言选项Regex 在XSLT中使用多个正则表达式:如何减少处理时间,regex,xml,xslt,saxon,Regex,Xml,Xslt,Saxon,我对编程和XSLT非常陌生:我试图改进提问和解释问题的方式,但我还有很长的路要走。对不起,如果有不清楚的地方 我需要检测XML文档中的各种字母表,看起来像这样,有更多不同的语言选项 <text> <p>Some text. dise´mbər Some text. Some text.</p> <!-- text in International Phonetic Alphabet + English --> <p>Some text.
<text>
<p>Some text. dise´mbər Some text. Some text.</p> <!-- text in International Phonetic Alphabet + English -->
<p>Some text. dise´mbər Some text. Издательство Академии Наук СССР Some text.</p> <!-- text in International Phonetic Alphabet + English + Cyrillic alphabet -->
<p>Some text. Издательство Академии Наук СССР dise´mbər Some text. Some text.</p>
<p>Some text. Some text. Издательство Академии Наук СССР Some text.</p> <!-- text in English + Cyrillic alphabet -->
</text>
一些文本。请看一些文字。一些文字。
一些文本。请看一些文字。部分文本。
一些文本。зззаааааааааааааааа1072。一些文本
一些文本。一些文本。部分文本。
我在XSLT中开始做的是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="xml" indent="no" encoding="UTF-8" omit-xml-declaration="no" />
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:for-each select="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="processing-instruction()">
<xsl:processing-instruction name="{local-name()}"><xsl:apply-templates></xsl:apply-templates></xsl:processing-instruction>
</xsl:template>
<xsl:template name="IPA">
<xsl:variable name="text" ><xsl:copy-of select="."/></xsl:variable>
<xsl:analyze-string select="$text" regex="((\p{{IsIPAExtensions}}|\p{{IsPhoneticExtensions}})+)" >
<xsl:matching-substring>
<IPA><xsl:value-of select="regex-group(1)"/></IPA>
</xsl:matching-substring>
<xsl:non-matching-substring><xsl:copy-of select="."></xsl:copy-of></xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template name="Cyrillic">
<xsl:variable name="texte" ><xsl:call-template name="IPA"></xsl:call-template></xsl:variable>
<xsl:analyze-string select="$texte" regex="(\p{{IsCyrillic}}+)" >
<xsl:matching-substring>
<Cyrillic><xsl:apply-templates select="regex-group(1)"/></Cyrillic>
</xsl:matching-substring>
<xsl:non-matching-substring><xsl:call-template name="IPA"></xsl:call-template></xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template match="text()">
<xsl:call-template name="Cyrillic"></xsl:call-template>
</xsl:template>
</xsl:stylesheet>
这样我就可以得到这样的XML:
<?xml version="1.0" encoding="UTF-8"?><text>
<p>Some text. dise´mb<IPA>ə</IPA>r Some text. Some text.</p>
<p>Some text. dise´mb<IPA>ə</IPA>r Some text. <Cyrillic>Издательство</Cyrillic> <Cyrillic>Академии</Cyrillic> <Cyrillic>Наук</Cyrillic> <Cyrillic>СССР</Cyrillic> Some text.</p>
<p>Some text. <Cyrillic>Издательство</Cyrillic> <Cyrillic>Академии</Cyrillic>
<Cyrillic>Наук</Cyrillic> <Cyrillic>СССР</Cyrillic> dise´mb<IPA>ə</IPA>r Some text. Some text.</p>
<p>Some text. Some text. <Cyrillic>Издательство</Cyrillic> <Cyrillic>Академии</Cyrillic>
<Cyrillic>Наук</Cyrillic> <Cyrillic>СССР</Cyrillic> Some text.</p>
</text>
一些文本。请看一些文字。一些文字。
一些文本。请看一些文字。部分文本。
一些文本。Издательство Академии
аааСССаdise'mbər一些文本。一些文本
一些文本。一些文本。Издательство Академии
部分文本。
这就是我所需要的,但是,我使用了大约十个regex块,如果我使用这种方法,处理时间将相当长。你会怎么做?您认为XSLT适用于此吗
谢谢大家!!
玛丽亚
(XSLT 2,萨克森HE 9.8.0.8)
编辑:以下是个人资料:
样式表执行时间分析
样式表执行时间分析
总时间:72128.065毫秒
在每个模板、函数或全局变量中花费的时间:
下表按模板函数中花费的总净时间排序
或全局变量。总时间是指包括调用的模板和函数在内的时间
(递归调用仅从原始条目开始计数);净时间是指不包括
花费在被调用的模板和函数上的时间。
文件
线
指示
计数
平均时间(总/毫秒)
总时间(总/毫秒)
平均时间(净/毫秒)
总时间(净/毫秒)
“*code/unicode.xsl”
21
模板希腊语
2,755,968
0.017
46,854.785
0.017
46,854.785
“*code/unicode.xsl”
32
希伯来语模板
1,329,696
0.043
57,529.163
0.008
10,674.378
“*code/unicode.xsl”
54
模板IPA
333,984
0.206
68,964.076
0.019
6,381.186
“*code/unicode.xsl”
43
模板西里尔
665,392
0.094
62,582.890
0.008
5,053.727
“*code/unicode.xsl”
65
模板阿拉伯语
167,068
0.421
70,284.800
0.008
1,320.724
“*code/unicode.xsl”
76
模板箭头
83,536
0.849
70,945.946
0.008
661.146
“*code/unicode.xsl”
8.
模板*
12,122
5.959
72,238.100
0.034
413.937
“*code/unicode.xsl”
87
模版蝙蝠
41,768
1.708
71,323.074
0.009
377.128
“*code/unicode.xsl”
98
模板专用
20,884
3.427
71,576.916
0.012
253.842
“*code/unicode.xsl”
18
模板处理-指令()
6,907
0.014
98.490
0.014
98.490
“*code/unicode.xsl”
121
模板文本()
20,884
3.429
71,600.976
0.001
24.060
在XSLT 3中,我将考虑以下方法:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="scripts"
as="map(xs:string, xs:string)*"
select="map { 'Cyrillic' : '\p{IsCyrillic}+'},
map { 'IPA' : '[\p{IsIPAExtensions}\p{IsPhoneticExtensions}]+' }"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="text()">
<xsl:iterate select="$scripts">
<xsl:param name="input" select="."/>
<xsl:on-completion>
<xsl:sequence select="$input"/>
</xsl:on-completion>
<xsl:next-iteration>
<xsl:with-param name="input">
<xsl:apply-templates select="$input" mode="wrap">
<xsl:with-param name="script-map" tunnel="yes" select="."/>
</xsl:apply-templates>
</xsl:with-param>
</xsl:next-iteration>
</xsl:iterate>
</xsl:template>
<xsl:mode name="wrap" on-no-match="shallow-copy"/>
<xsl:template match="text()" mode="wrap">
<xsl:param name="script-map" tunnel="yes"/>
<xsl:analyze-string select="." regex="{$script-map?*}">
<xsl:matching-substring>
<xsl:element name="{map:keys($script-map)}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
我没有测量它是否执行得更好,但是对于正则表达式,我将<代码> [\p{iSpAdExt} \ p{iSosieExtExp}}[+/Case]认为比<代码>(\ p{isiPaultExt} \ p{iSouthExtExt})更容易[+/c>>/p>
其他改进是依靠基于xsl:mode
的标识转换和xsl:iterate
正则表达式,如\p{IsIPAExtensions}
应该相当有效:大多数块都是一个连续的码点范围,测试字符只需检查字符是否在该范围内即可。我猜想,成本并不是来自检查一个字符与一个Unicode块的成本,而是来自字符数和块数
在Java级别获得一个概要文件,看看它在哪里花费时间,这可能是值得的。我可以猜测,但如果我的猜测是正确的,个人资料就会显示出来
使用正则表达式会降低性能的是回溯,但我并没有立即看到使用此代码进行回溯的任何风险
唯一想到的另一种方法是生成一个巨大的translate()
调用,将字符分类为组(因此所有拉丁字符变为“1”,所有西里尔字符变为“2”,等等),然后处理