当前位置: 首页 > 知识库问答 >
问题:

无法让“s”标志在撒克逊9.5的正则表达式中工作

莘康裕
2023-03-14

我有一个XML信封/有效负载结构,如下所示:

<RootEnvelopeTag>
    <EnvelopeTag />
    <EnvelopeTag />
    <EnvelopeTagContainingPayload>
        &lt;WantedPayloadTag&gt;Some text and nested tags.&lt;/WantedPayloadTag&gt;&lt;UnwantedPayloadTag&gt;Lots of text and nested tags.&lt;/UnwantedPayloadTag&gt;
    </EnvelopeTagContainingPayload>
</RootEnvelopeTag>

为了提取有效负载,通过删除所有信封元素,我使用以下XSLT:

<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
  <xsl:output method="text" encoding="utf-8"/>
  <xsl:template match="/">
    <xsl:apply-templates select="*/EnvelopeTagContainingPayload"/>
  </xsl:template>
  <xsl:template match="EnvelopeTagContainingPayload">
    <xsl:value-of select="."/>
  </xsl:template>
</xsl:transform>

结果是一个新的文本文件,一旦解析为XML,就允许我只使用有效负载XML。

这在Saxon HE 9.5和AltovaXML 2013中都运行良好。但是,我现在还需要删除部分有效负载,特别是一个元素,包括标签及其所有内容(

由于在原始XML文件中,有效负载只是一个字符串,因此我使用替换()与匹配不需要的元素和空字符串作为替换字符串的正则表达式。我包含“s”标志,以获取“.”在正则表达式中匹配不需要的元素中存在的换行符。因此,容器信封元素的模板更改为:

  <xsl:template match="EnvelopeTagContainingPayload">
    <xsl:variable name="removeUnwanted" as="xs:string" select="replace(., '&lt;UnwantedPayloadTag.*UnwantedPayloadTag&gt;', '', 's')" />
    <xsl:value-of select="$removeUnwanted"/>
  </xsl:template>

在AltovaXML中,这可以无缝工作。结果与预期完全一致。但在撒克逊,它造成了巨大的破坏。未生成输出;相反,我在命令行中不断重复以下错误消息,使整个DOS命令行窗口混乱不堪:

净利润。旧金山。撒克逊人。正则表达式。操作$OpStar。exec(Operation.java:235)

net.sf.saxon.regex.REMatcher.match节点(REMatcher.java:413)

只有当我使用“s”标志时,问题才会出现。但如果我把它扔了,我就赢不了比赛。我尝试了一种不需要标志的替代方案,并且做了相同的操作:

    <xsl:variable name="removeUnwanted" as="xs:string" select="replace(., '&lt;UnwantedPayloadTag[\s\S]*UnwantedPayloadTag&gt;', '')" />

但我在萨克森身上也有同样的错误。再一次,阿尔托娃做对了。我不确定问题是否出在我的代码上,因为它在Altova中运行良好。但我真的很想让这个在撒克逊也能用上。那么,怎么了?

共有2个答案

萧鹏云
2023-03-14

由于回溯太多,您在Saxon正则表达式引擎中遇到堆栈溢出。我们在未来的9.6版本中对此进行了修复,但与此同时,您需要小心执行过多回溯的正则表达式。

真的,你的方法是错误的。正则表达式不应用于解析XML。您的表达式是错误的,因为它可以匹配不应该匹配的内容,例如注释中看起来像结束标记的内容。通过调整regex是无法正确实现的,因为XML具有递归语法,而正则表达式无法处理递归语法。Saxon为此提供了parse-xml()。

赵宏达
2023-03-14

由于Saxon 9.6现在可用,甚至在家庭版中,他也支持XPath 3.0函数,如解析xml片段,因此解决问题的正确方法现在正在实施

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

  <xsl:output method="xml" encoding="utf-8"/>

  <xsl:template match="/">
    <xsl:apply-templates select="*/EnvelopeTagContainingPayload"/>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* , node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="EnvelopeTagContainingPayload">
    <xsl:apply-templates select="parse-xml-fragment(.)"/>
  </xsl:template>

  <xsl:template match="UnwantedPayloadTag"/>

</xsl:transform>

这样,您只需将标记解析为XML,然后使用模板过滤掉任何不需要的元素

 类似资料:
  • 问题内容: 这个问题已经在这里有了答案 : 字符串替换方法不替换字符 (5个答案) 2年前关闭。 我正在尝试将所有特殊字符替换为“%”,例如: 我的正则表达式是: 在在线工具中*它可以正常运行,但在Java中 弦保持不变。 *我尝试过:http : //www.regexplanet.com/ http://regex101.com/和其他 问题答案: 字符串是不可变的。您忘了将新变量重新分配给:

  • 克隆一个正则表达式。 使用 new RegExp() , RegExp.source 和 RegExp.flags 来克隆给定的正则表达式。 const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags); const regExp = /lorem ipsum/gi; const regExp2 = cloneRegE

  • 我已经为名称验证创建了一个正则表达式,其中只允许“_”、“-”、“'”、“.”。 以下是正则表达式: 问题是这是其允许的名称有< code>@,检查小提琴演示: 应为:不应允许包含< code>@的名称。 注意:当我在https://regex101.com/#javascript测试这个正则表达式时,它运行良好

  • 问题内容: 我需要这样的匹配器: 问题是它不是简单的ASCII。我知道在这种特殊情况下,我可以将[\ u00FC \ u00DC]用于ü,但是我需要更加通用(从其他匹配器组构建正则表达式)。所以根据javadocs: 默认情况下,不区分大小写的匹配假定只匹配US- ASCII字符集中的字符。可以通过将UNICODE_CASE标志与该标志一起指定来启用Unicode感知的不区分大小写的匹配。 谁能告

  • 下面是我正在使用的正则表达式的最新版本,它抛出了错误“Invalid regular expression” XSD:正则表达式在位置4验证失败:当前选项设置不支持此表达式。 我在xsd文件中得到了这个异常,我正在message broker(IIB)中开发这个xsd。有谁能帮我解决这个问题吗?

  • 问题内容: 因此,我对 正则表达式 完全 陌生 ,并且正在尝试使用Java 来查找输入字符串中的标点符号。我不知道会提前得到哪种标点符号,只是(1)!,?,。,…都是有效的标点符号,以及(2)“ <”和“>”表示特殊含义,并且不算作标点符号。该程序本身会伪随机地构建短语,我想在它经历随机过程之前先删除句子结尾处的标点符号。 我可以用任何标点符号匹配整个单词,但匹配器只为我提供该单词的索引。换一种说