Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT中与和条件的交叉引用_Xslt_Xslt 2.0_Cross Reference - Fatal编程技术网

XSLT中与和条件的交叉引用

XSLT中与和条件的交叉引用,xslt,xslt-2.0,cross-reference,Xslt,Xslt 2.0,Cross Reference,我试图交叉引用外部XML文件,但不是只比较一个键,而是询问是否存在一个字符串和其他字符串,以及是否存在来自外部文件的引用: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:t="http://w

我试图交叉引用外部XML文件,但不是只比较一个键,而是询问是否存在一个字符串和其他字符串,以及是否存在来自外部文件的引用:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:t="http://www.tei- 
c.org/ns/1.0"
xmlns="http://www.tei-c.org/ns/1.0" exclude-result-prefixes="xs t">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="ids"
    select="document('instructions.xml')"/>

<xsl:key name="id" match="row" use="tokenize(normalize-space(elem[@name='Instruction']), ' ')"/>


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

<xsl:template match="instruction">
    <xsl:for-each select=".[contains(.,key('id', ., .))]">
    <xsl:copy>     
        <xsl:attribute name="norm">
            <xsl:value-of select="normalize-space(key('id', normalize-space(.), $ids)/elem[@name='Norm'])"/>
        </xsl:attribute>
        <xsl:apply-templates select="@* | node() | text() | *"/>   
    </xsl:copy>
    </xsl:for-each>
</xsl:template>

输入(外部文件):


倾吐
p1
输入(要注释的文件):


布拉布拉
把牛奶倒出来
期望输出:

<ab type="recipe">
Bla bla
  <instruction norm="p1">pour the milk out</instruction> bla
</ab>

布拉布拉
把牛奶倒出来
顺序词:元素
中的外部XML文件中的标记“pour”和“out”都需要包含在我的XML文件中的
元素中。如果是,我想在外部文件中将norm属性设置为
的值


非常感谢任何帮助

我不知道如何使用钥匙,但我找到了另一种方法

<xsl:template match="instruction">
    <xsl:variable name="words" select="tokenize(normalize-space(.), ' ')" />
    <xsl:variable name="row" select="$ids//row[every $i in tokenize(normalize-space(elem[@name='instruction']), ' ') satisfies $i = $words]" />
    <xsl:copy>
        <xsl:if test="$row">
            <xsl:attribute name="norm" select="$row/elem[@name='norm']" />    
        </xsl:if>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

编辑:为了回应您的评论,如果您可以有多行匹配,那么要获得匹配单词最多的一行,请执行以下操作

<xsl:template match="instruction">
    <xsl:variable name="words" select="tokenize(normalize-space(.), ' ')" />
    <xsl:variable name="row" as="element()*">
        <xsl:perform-sort select="$ids//row[every $i in tokenize(normalize-space(elem[@name='instruction']), ' ') satisfies $i = $words]">
            <xsl:sort select="count(tokenize(normalize-space(elem[@name='instruction']), ' '))" order="descending" />
        </xsl:perform-sort>
    </xsl:variable>
    <xsl:copy>
        <xsl:if test="$row">
            <xsl:attribute name="norm" select="$row[1]/elem[@name='norm']" />    
        </xsl:if>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>


由于
elem name=“instruction”
元素包含您标记的单词列表,那么
指令
元素中单词的顺序是否重要,即它是否必须包含相同顺序的单词(
倾倒
取出
)?没有顺序根本不重要!“出布拉布拉倒”也应该匹配。然而,我有一种情况,我可以在输入数据中用另一个范数值“倒”。“倒出-->p1”、“倒出-->p0”。如果它实际包含所有单词,则最好首先匹配。所以在这个例子中,p1。如果是“倒牛奶”,应该是p0。这是一个非常好的方法!我只是想问您是否也知道如何处理输入数据中出现另一个“norm”的相同单词的情况:
pour out p1 pour p0
使用您的解决方案,我现在得到了
。是否只输出第一个,还是包含最多单词的行?首先是包含最多匹配单词的行。如果句子是“倒牛奶”,那么实际上应该是p0。但是“把牛奶倒出来”应该是p1。谢谢你!另一方面,
node()
实际上是
*| text()| comment()| processing-instruction()
的简写,所以这样做
node()| text()|*
可以直接缩短为
node()
<xsl:template match="instruction">
    <xsl:variable name="words" select="tokenize(normalize-space(.), ' ')" />
    <xsl:variable name="row" select="$ids//row[every $i in tokenize(normalize-space(elem[@name='instruction']), ' ') satisfies $i = $words]" />
    <xsl:copy>
        <xsl:if test="$row">
            <xsl:attribute name="norm" select="$row/elem[@name='norm']" />    
        </xsl:if>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="instruction">
    <xsl:variable name="words" select="tokenize(normalize-space(.), ' ')" />
    <xsl:variable name="row" as="element()*">
        <xsl:perform-sort select="$ids//row[every $i in tokenize(normalize-space(elem[@name='instruction']), ' ') satisfies $i = $words]">
            <xsl:sort select="count(tokenize(normalize-space(elem[@name='instruction']), ' '))" order="descending" />
        </xsl:perform-sort>
    </xsl:variable>
    <xsl:copy>
        <xsl:if test="$row">
            <xsl:attribute name="norm" select="$row[1]/elem[@name='norm']" />    
        </xsl:if>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>