是否可以替换/替换传入的XSL数据?

时间:2012-07-17 20:09:19

标签: xml xslt substitution

我试图在谷歌上寻找答案,但我得到的结果是如何替换字符串或替换子字符串等。但我的问题略有不同。

假设我有一个现有的XSL模板,比如“ hello-world ”,它处理“数据/记录/记录”,但我不能修改你好-world ,所以我想创建一个包装器模板,在将每个记录传递给 hello-world 之前按下/修改每个记录中的数据......有没有办法做是什么?

到目前为止,我已经设法创建了一个可以过滤掉重复记录的函数,我正在考虑用新的记录替换“data / records / *”中的所有记录......

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


    <xsl:template match="/">
        <xsl:call-template name="get-unique-record">
            <xsl:with-param name="records" select="/data/records/record"/>
        </xsl:call-template>
    </xsl:template>

    <!-- This function will filter out the given records and return a unique set of records -->
    <xsl:key name="kField_ID" match="field[@name='ID']" use="."/>
    <xsl:template name="get-unique-record">
        <xsl:param name="records"/>
        <xsl:for-each select="$records">
            <xsl:variable name="record" select="."/>
            <xsl:if test="$record//field[generate-id() = generate-id(key('kField_ID', .))]">
            <xsl:copy-of select="$record"/>         
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

现在......可以做类似的事情:

<xsl:variable name="/data/records/record">
    <xsl:call-template name="get-unique-record">
        <xsl:with-param name="records" select="/data/records/record"/>
    </xsl:call-template>
</xsl:variable>
编辑:@LasrH,感谢您的快速回复。有没有办法复制现有的“/”,然后将所有/ data / records / record替换为已过滤的?/ / p>

EDIT2:@LasrH,我创建了几个模板来修改和重建“数据”节点。是否可以使用node-set来“替换”现有输入和我的新数据作为输入?

<xsl:variable name="data">
    <xsl:call-template name="rebuild-data-with-record">
        <xsl:with-param name="records">
                    <xsl:copy-of select="$unique-records"></xsl:copy-of>
                    </xsl:with-param>
    </xsl:call-template>
</xsl:variable>

然后我进一步尝试使用这样的节点集:

<xsl:apply-templates select="exslt:node-set($data)/data"/>

但它看起来并不像是在做...也没有抛出任何错误。

2 个答案:

答案 0 :(得分:1)

不,在XSL中,您无法就地修改源文档。

但是,您可以按上游源文档(使用单独的XSL样式表),并将按摩文档传递给调用“hello-world”模板的XSL样式表,而不是让它处理原始源文档。

如果您能够修改该样式表,您甚至可以在包含“hello-world”的相同样式表中执行此操作。 (但我想你不能修改那个样式表,或者你可以修改“hello-world”。)

答案 1 :(得分:1)

实际上,经过大量研究和试验,您可以在XSL级别“替换/替换”数据!您只需要自己重建根节点,并将您的“修改后的根”(RTF将其转换回节点集)传递给您的模板,并让您的模板从您自己的数据中读取它!

我在这里问了另一个问题,这是我实验的一部分: Unable to cast from XRTreeFrag into XNodeSet

这个想法是这样的,你有一个读取/处理传入数据的模板函数,我们几乎总是从root / blah / blah / blah中读取输入...而不是从root读取它,你可以在每个/你的模板中执行此操作:

<xsl:template name="helloworld">
    <xsl:param name="inputRoot" select="/"/>
    <xsl:variable name="root" select="$inputRoot"/>
    rest of your code goes here...

现在,用$ root / blah / blah / blah替换你的所有root访问权限,它将接收你修改过的XSL数据!

关于这一点很酷的是,如果你没有传递任何输入数据,它只会假设输入为root! ;)

经过测试,完美无瑕。然而,我只有一个问题,如果XSL输入是巨大的,重建整个根可能会导致性能问题。但我的输入只有二十多条记录,而且我的案例没有任何性能影响。

因此,您可能需要仔细检查输入数据是否很大。

此解决方案/方法是XSL 1.0友好的。