如何匹配给定句子中的关键字以创建Schematron表达式XSLT 2.0或3.0

时间:2019-03-07 09:21:03

标签: xml xslt-2.0 xslt-3.0

一段时间以来,我一直在处理一个问题,即有多个给定的句子和关键字,我需要匹配关键字并在句子中找到它们,然后根据每个关键字的句子顺序创建另一个字符串

因此,关键字列表不必遵循与句子中相同的顺序。但是顺序应该与句子中的顺序相匹配。希望一切都清楚。

XML示例:

<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<LIST>
    <ID>1</ID>
    <MESSAGE>Cats(13) are "lovely" or "beautiful" and Dogs(10) are "loyal" or "friendly".</MESSAGE>
</LIST>
<LIST>
    <ID>2</ID>
    <MESSAGE>Horses(11) are not a "good" option and Pigs(12) are okay</MESSAGE>
</LIST>
<ADJS>
    <ADJ>lovely</ADJ>
</ADJS>
<ADJS>
    <ADJ>friendly</ADJ>
</ADJS>
<ADJS>
    <ADJ>beautiful</ADJ>
</ADJS>
<ADJS>
    <ADJ>loyal</ADJ>
</ADJS>
<ADJS>
    <ADJ>good</ADJ>
</ADJS>
 <ADJS>
    <ADJ>okay</ADJ>
</ADJS>
<KEYWORDS>
    <ID>10</ID>
    <KEYWORD>Dogs</KEYWORD>
</KEYWORDS>
<KEYWORDS>
    <ID>11</ID>
    <KEYWORD>Horses</KEYWORD>
</KEYWORDS>
<KEYWORDS>
    <ID>12</ID>
    <KEYWORD>Pigs</KEYWORD>
</KEYWORDS>
<KEYWORDS>
    <ID>13</ID>
    <KEYWORD>Cats</KEYWORD>
</KEYWORDS>
<KEYWORDS>
    <ID>14</ID>
    <KEYWORD>aquarium</KEYWORD>
</KEYWORDS>
<KEYWORDS>
    <ID>b</ID>
    <KEYWORD>Fishes</KEYWORD>
</KEYWORDS>
<OP>
    <SYNTAX>and</SYNTAX>
</OP>
<OP>
    <SYNTAX>or</SYNTAX>
</OP>
<OP>
    <SYNTAX>are not</SYNTAX>
</OP>
<OP>
    <SYNTAX>are</SYNTAX>
</OP>

我尝试过的

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:functx="http://www.functx.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:function name="functx:contains-any-of" as="xs:boolean">
    <xsl:param name="arg" as="xs:string?"/>
    <xsl:param name="searchStrings" as="xs:string*"/>
    <xsl:sequence select="
            some $searchString in $searchStrings
                satisfies contains($arg, $searchString)
            "/>
</xsl:function>
<xsl:template match="ROOT">
    <xsl:variable name="keyID" select="//KEYWORDS/ID"/>
    <xsl:variable name="keyName" select="//KEYWORDS/KEYWORD"/>
    <xsl:variable name="keyOp" select="//OP/SYNTAX"/>
    <xsl:for-each select="//MESSAGE">
        <xsl:variable name="message" select="node()"/>
        <xsl:if test="functx:contains-any-of($message, $keyID)">

            <xsl:element name="test">
                <xsl:value-of select="$keyName"/>
                <xsl:value-of select="$keyOp"/>
            </xsl:element>

            </xsl:if>
    </xsl:for-each>
</xsl:template>

预期输出:

<test>Cats = ('lovely','beautiful') and Dogs = ('loyal','friendly')</test>
<test>Horses != 'good' or Pigs = 'okay'</test> 

问题是,这里的所有内容都是从Excel文件转换而成的,我想做的是具有自动转换功能。从Excel到Schematron。在这一部分中,我已经将Excel转换为XML。

现在,我正在尝试通过使用关键字从句子中获取Xpath定义。因为,这些关键字是动态的。如果有机会使用excel,则必须一直更改为schematron。

我需要按句子的顺序在句子中找到那些关键字。以及运算符和形容词。因此,我可以尝试在预期的输出中创建表达式。

我无法更改句子的顺序或结构。这里的主要思想是从句子中创建Xpath定义。

更新

因此,我从Martin Honnen的一篇文章中了解到,在XSLT 2.0中,$name = ('Alice', 'Bob', 'Cindy')是可能的。

UPDATE-2

<xsl:variable name="operator" select="$btbg/node()/SimpleCodeList/Row/Value[@ColumnRef = 'DictionaryEntryName']/SimpleValue/text()"/>
<xsl:copy>
        <xsl:variable name="w" select="tokenize(., '\s+')"/>
        <xsl:value-of select="$w[position() &gt; index-of($w, $w[. = $operator][1])]"/>
</xsl:copy>

我在想这个主意,就是在找到关键字后将句子循环放到最后。但也无法使其正常工作。 $operator参数来自另一个XML文件。如果我以这种方式进行操作,则无法递归获得该值。它会读取XML中的所有运算符或任何其他参数。

我想一个接一个地选择节点,然后在句子中找到它们。然后在读取值之后将句子切到那里,然后将句子再次放入下一个关键字的循环中。

我该如何克服这个问题?预先感谢。

0 个答案:

没有答案