匹配<! - [CDATA] - >

时间:2017-10-15 12:30:35

标签: string xslt xpath cdata

我有一个使用<![CDATA["text"]]>来表示字符串值的DMN文档。我正在尝试输入字符串中的所有单词对照这些CDATA部分中的一个字符串,但我无法弄清楚哪个XPath表达式可以解决问题。

以下是DMN文件示例:

<definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd" id="definitions_0fyde0d"
name="definitions" namespace="http://camunda.org/schema/1.0/dmn">
<decision id="decision" name="TroubleArea">
    <decisionTable id="decisionTable">
        <input id="input1" label="UserText">
            <inputExpression id="inputExpression1" typeRef="string">
                <text/>
            </inputExpression>
        </input>
        <output id="output1" label="Subsystem" name="" typeRef="string"/>
        <rule id="row-22012340-2">
            <inputEntry id="UnaryTests_1hacpom">
                <text><![CDATA["signal", "input", "connection"]]></text>
            </inputEntry>
            <outputEntry id="LiteralExpression_0wvuvyc">
                <text><![CDATA["input"]]></text>
            </outputEntry>
        </rule>
        <rule id="row-22012340-3">
            <inputEntry id="UnaryTests_0cmpu76">
                <text><![CDATA["screen"]]></text>
            </inputEntry>
            <outputEntry id="LiteralExpression_0hkc81e">
                <text><![CDATA["output"]]></text>
            </outputEntry>
        </rule>
    </decisionTable>
</decision>

输入是单个字符串,需要与<inputEntry>元素的CDATA部分中的引号之间的任何字符串进行匹配。找到匹配项后,我需要返回同一<outputEntry>的{​​{1}}中的字符串。

将命名空间添加到我的XSL后,我可以匹配<rule>,但我仍然没有在任何字符串上获得任何匹配。这是我用来检查是否有匹配的代码。这还没有获得<decisionTable>字符串,只是“是”或“否”告诉我是否存在匹配。

<outputEntry>

使用输入字符串“some%20with%20the%20screen%20或%20the%20screen%20brightness”测试此结果:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:dmn="http://www.omg.org/spec/DMN/20151101/dmn.xsd"
exclude-result-prefixes="xs"
version="2.0">

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

<xsl:param name="input"/>

<xsl:template match="/">
    <result>
        <xsl:variable name="table">
            <xsl:value-of select="//dmn:decisionTable"/>
        </xsl:variable>
        <xsl:for-each select="distinct-values(tokenize($input,'%20'))">
            <item>
                <xsl:value-of select="."/>
                <xsl:text>: </xsl:text>
                <xsl:call-template name="matchrule">
                    <xsl:with-param name="text">
                        <xsl:value-of select="concat('&quot;',.,'&quot;')"/>
                    </xsl:with-param>
                    <xsl:with-param name="table">
                        <xsl:value-of select="$table"/>
                    </xsl:with-param>
                </xsl:call-template>
            </item>
        </xsl:for-each>     
    </result>
</xsl:template>

<xsl:template name="matchrule">
    <xsl:param name="table"/>
    <xsl:param name="text"/>
        <xsl:choose>
            <xsl:when test="$table//dmn:rule[contains(dmn:inputEntry/dmn:text,$text)]">
                <xsl:text>Yes</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>No</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
</xsl:template>

我无法将DMN更改为不使用这些result xmlns:dmn="http://www.omg.org/spec/DMN/20151101/dmn.xsd"> <item>something: No</item> <item>with: No</item> <item>the: No</item> <item>screen: No</item> <item>or: No</item> <item>brightness: No</item> 条目,因为该表是由我无法控制的其他工具创建的。

1 个答案:

答案 0 :(得分:1)

我认为一种方法是使用

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xpath-default-namespace="http://www.omg.org/spec/DMN/20151101/dmn.xsd"
exclude-result-prefixes="xs"
version="2.0">

<xsl:output method="xml" indent="yes" encoding="UTF-8"/>

<xsl:param name="input">something%20with%20the%20screen%20or%20the%20screen%20brightness</xsl:param>

<xsl:template match="/">
    <result>
        <xsl:variable name="rules" select="//rule"/>

        <xsl:for-each select="distinct-values(tokenize($input,'%20'))">
            <item>
                <xsl:value-of select="."/>
                <xsl:text>: </xsl:text>
                <xsl:apply-templates select="$rules[inputEntry/text[contains(., concat('&quot;', current(), '&quot;'))]]"/>
            </item>
        </xsl:for-each>     
    </result>
</xsl:template>

<xsl:template match="rule">
    <xsl:value-of select="outputEntry/text"/>
</xsl:template>

</xsl:stylesheet>

输出

<result>
   <item>something: </item>
   <item>with: </item>
   <item>the: </item>
   <item>screen: "output"</item>
   <item>or: </item>
   <item>brightness: </item>
</result>

在线示例http://xsltransform.net/gVhD8RW