xslt - 在 xslt 2.0 中使用正确的正则表达式

标签 xslt xslt-2.0

我一直在使用正确的正则表达式。我需要对每个键的每个数据以及这些值进行标记。在我下面的示例中,

示例文件:

<Rec>
   <Data>/CHG1/EUR1000,00/EXCH/0,10/CPRP/Payment Code 1</Data>
   <Data>/CHG1/EUR1000,00/EXCH/0,10/CPRP/Payment Code 1</Data>
   <Data>/CHG3/EUR3000,00/PURP//CD/Payment Code 3</Data>
   <Data>/CHG5/EUR5000,00/PURP//PRTRY/Payment Code 5</Data>
   <Data>/ORIG//CSID/EUR7000,00/BENM//ID/Payment Code 7</Data>
</Rec>

中间带有'//'的按键被视为1个按键。我需要生成这样的输出:

<Data>
   <Group>
      <Token>/CHG1/EUR1000,00</Token>
      <Token>/EXCH/0,10</Token>
      <Token>/CPRP/Payment Code 1</Token>
   </Group>
   <Group>
      <Token>/CHG3/EUR3000,00</Token>
      <Token>/PURP//CD/Payment Code 3</Token>
   </Group>
   <Group>
      <Token>/CHG5/EUR5000,00</Token>
      <Token>/PURP//PRTRY/Payment Code 5</Token>
   </Group>
   <Group>
      <Token>/ORIG//CSID/EUR7000,00</Token>
      <Token>/BENM//ID/Payment Code 7</Token>
   </Group>
</Data>

但是,我生成的输出是这样的:

<Data>
   <Group>
      <Token>/CHG1/</Token>
      <Token>/EXCH/</Token>
      <Token>/CPRP/</Token>
   </Group>
   <Group>
      <Token>/CHG3/</Token>
      <Token>/PURP//CD/</Token>
   </Group>
   <Group>
      <Token>/CHG5/</Token>
      <Token>/PURP//PRTRY/</Token>
   </Group>
   <Group>
      <Token>/ORIG//CSID/</Token>
      <Token>/BENM//ID/</Token>
   </Group>
</Data>

这是我一直在使用的 XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()[boolean(normalize-space())]|@*"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="Data">
    <xsl:for-each select=".">
        <Group>
            <xsl:analyze-string select="." regex="\/[A-Z]+[0-9]?\/(\/(CD|PRTRY|MARF|ID|CSID|NAME|RID)\/)?">
                <xsl:matching-substring>
                    <xsl:variable name="val" select="."/>
                    <Token>
                        <xsl:value-of select="$val"/>
                    </Token>
                </xsl:matching-substring>
            </xsl:analyze-string>
        </Group>
    </xsl:for-each>
</xsl:template>

我的正则表达式中缺少一些内容。谁能帮我弄清楚吗?感谢您的反馈。

最佳答案

我无法确定您的预期输出。我怀疑正确的输出实际上应该是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<Rec>
   <Group>
      <Token>CHG1/EUR1000,00</Token>
      <Token>EXCH/0,10</Token>
      <Token>CPRP/Payment Code 1</Token>
   </Group>
   <Group>
      <Token>CHG1/EUR1000,00</Token>
      <Token>EXCH/0,10</Token>
      <Token>CPRP/Payment Code 1</Token>
   </Group>
   <Group>
      <Token>CHG3/EUR3000,00</Token>
      <Token>PURP/</Token>
      <Token>CD/Payment Code 3</Token>
   </Group>
   <Group>
      <Token>CHG5/EUR5000,00</Token>
      <Token>PURP/</Token>
      <Token>PRTRY/Payment Code 5</Token>
   </Group>
   <Group>
      <Token>ORIG/</Token>
      <Token>CSID/EUR7000,00</Token>
      <Token>BENM/</Token>
      <Token>ID/Payment Code 7</Token>
   </Group>
</Rec>

如果是这样,我建议您改变方法并尝试:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="Data">
    <xsl:variable name="t" select="tokenize(., '/')" />
    <Group>
        <xsl:for-each select="$t[position() mod 2 = 0]">
            <xsl:variable name="i" select="index-of($t, .)"/>
            <Token>
                <xsl:value-of select="." />
                <xsl:text>/</xsl:text>
                <xsl:value-of select="$t[$i + 1]" />
            </Token>
        </xsl:for-each>
    </Group>
</xsl:template>

</xsl:stylesheet>

演示:http://xsltransform.net/93dEHGr


或者更简单:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="Data">
    <Group>
        <xsl:for-each-group select="tokenize(., '/')" group-by="position() idiv 2">
            <Token>
                <xsl:value-of select="current-group()" separator="/"/>
            </Token>
        </xsl:for-each-group>
    </Group>
</xsl:template>

</xsl:stylesheet>

演示:http://xsltransform.net/93dEHGr/2


添加:

Actually, the keys with 2 '//' in the middle is considered as 1 key.

那么,让我们在进行标记化之前将 // 字符串从游戏中取出,并在最后恢复它们:

<xsl:template match="Data">
    <Group>
        <xsl:for-each-group  select="tokenize(replace(., '//', '§§§'), '/')" group-by="position() idiv 2">
            <Token>
                <xsl:value-of select="replace(string-join(current-group(), '/'), '§§§', '//')" />
            </Token>
        </xsl:for-each-group>
    </Group>
</xsl:template>

结果

<?xml version="1.0" encoding="UTF-8"?>
<Rec>
   <Group>
      <Token/>
      <Token>CHG1/EUR1000,00</Token>
      <Token>EXCH/0,10</Token>
      <Token>CPRP/Payment Code 1</Token>
   </Group>
   <Group>
      <Token/>
      <Token>CHG1/EUR1000,00</Token>
      <Token>EXCH/0,10</Token>
      <Token>CPRP/Payment Code 1</Token>
   </Group>
   <Group>
      <Token/>
      <Token>CHG3/EUR3000,00</Token>
      <Token>PURP//CD/Payment Code 3</Token>
   </Group>
   <Group>
      <Token/>
      <Token>CHG5/EUR5000,00</Token>
      <Token>PURP//PRTRY/Payment Code 5</Token>
   </Group>
   <Group>
      <Token/>
      <Token>ORIG//CSID/EUR7000,00</Token>
      <Token>BENM//ID/Payment Code 7</Token>
   </Group>
</Rec>

http://xsltransform.net/93dEHGr/4

关于xslt - 在 xslt 2.0 中使用正确的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45911708/

相关文章:

css - 从简单的 XML 文件到 XForms 的 XSL 转换并应用 CSS

java - 如何在 Java 中使用 .sef 文件运行 XSLT 转换

c# - Xml解析器 : XSLT compiler error

xml - 多个xsl选择条件

python - 将撒克逊与 python 一起使用

xml - XSLT - 添加新元素和属性

regex - XSLT - 检查元素字符串中是否存在模式

html - html 页面上的不同 XML 数据

xml - 节点计数和出现 - XSL

xslt - 使用 xslt 替换功能将单词替换为元素