【问题标题】:xsltProcessor setParameter : send an undefined number of paramsxsltProcessor setParameter : 发送未定义数量的参数
【发布时间】:2012-11-04 13:22:07
【问题描述】:

我有一个 XSL 文件。

我有一个带有名为$bob 的 XSLTProcessor 的 PHP 文件。

我想向我的 xsl 转换发送一些参数。

所以,我把它写在我的 PHP 文件中;例如:

$bob->setParameter('', 'message', 'hi');

在我的 XSL 文件中,要获取参数,我会这样写:

<xsl:param name="message" />

如果我想在我的 XSL 中显示这个参数,我会这样做:

<xsl:value-of select="$message" />

问题来了。

我必须向我的 XSL 发送未定义数量的参数,但我不知道该怎么做。我尝试了几种解决方案,但它们不相关。例如,我想向我的 XSL 发送 3 条消息,并且我希望我的 XSL 使用它们来生成这样的代码:

<messages>
    <message>Hi</message>
    <message>it's bob</message>
    <message>How are you ?</message>
</messages>

你有我的解决方案吗? 这将是非常好的。 对不起,如果我的英语有错误。 谢谢你,祝你有美好的一天。

如被问及,这就是我所拥有和想要拥有的

(以下分开)

这是我原始 XML 的简化版本,名为 posts.xml:

<posts>
    <post id="post1" >
        <titre>Hey</titre>
        <motscles>
            <motcle>Batman</motcle>
            <motcle>Cats</motcle>
        </motscles>
    </posts>
</posts>

这是我想在 final 中使用的 XML:

<posts>
    <post id="post1" >
        <titre>Hey</titre>
        <motscles>
            <motcle>Batman</motcle>
            <motcle>Cats</motcle>
        </motscles>
    </posts>
    <post id="post2" >
        <titre>Toto</titre>
        <motscles>
            <motcle>Superman</motcle>
            <motcle>Dogs</motcle>
            <motcle>Cake</motcle>
        </motscles>
    </posts>
</posts>

我通过 HTML 表单获得了帖子的信息(标题,motscles)。 所以我的 php 文件获取信息,并将其发送到我的 XSL 文件:

// initialize xml and xsl
$xml = new DOMDocument();
$xml->load('posts.xml');
$xsl = new DOMDocument();
$xsl->load('addpost.xsl');

// Initialize the XSLTProcessor
$addPost  = new XSLTProcessor();
$addPost->importStylesheet($xsl);

// Define parameters
$addPost->setParameter('', 'titre', $_POST['titre']);

// Get the modified xml
$xml = $addPost->transformToDoc($xml);

// Save the modified xml
$xml->save('posts.xml');

这是我的 XSL 的简化版本:

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

    <xsl:param name="titre" />
    <xsl:param name="motscles" />

    <xsl:template match="posts" >
        <xsl:copy>

            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="@*|node()"/>

            <xsl:call-template name="post" />
        </xsl:copy>
    </xsl:template>

    <!-- Template de post -->
    <xsl:template name="post" >
        <post id="{$id}" >
            <titre><xsl:value-of select="$titre" /></titre>
            <motscles>
            </motscles>
        </post>
    </xsl:template>

    <!-- Copier les nodes et attributs récursivement -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
   </xsl:template>  

</xsl:stylesheet>

【问题讨论】:

  • 您转换的原始 XML 是什么?你的 XSL XML 是什么?您只有一小部分可以很好地解释您的问题,但是,由于setParameter 只允许为每个名称设置一个值,因此不清楚您要做什么。原始的 XML 和 XSL 会更清楚一些。
  • user1786510:您可能对比使用竖线分隔的字符串更灵活和可扩展的解决方案感兴趣。

标签: php xslt parameters


【解决方案1】:

我只需要 一个 参数,即 XML 文档。我会在调用转换之前创建这个 XML 文档。

与发送单个管道分隔的字符串相比,这具有一些明确的好处

  1. 每个参数都在自己的元素中,这可以通过 XSLT 中的单独模板进行匹配。

  2. 不需要对管道分隔的字符串进行递归处理,也不需要扩展函数。

  3. 更具可扩展性和可扩展性。

【讨论】:

  • 这是一个比使用管道分隔的字符串更简洁的解决方案,尤其是在 XSLT 1.0 不支持 tokenize() 函数的情况下。
  • 理论上我同意传入 XML 文档更好,但根据 php.net/manual/en/xsltprocessor.setparameter.php#74864 PHP 分别 libxslt 不支持 DOMDocument 或节点的参数。 PHP 使用的 libxslt 支持 EXSLT 标记化,所以我认为我的答案对于标记为 PHP 和 XSLT 的问题是一个实用的选择。如果问题发布者使用的 XSLT 处理器根本无法使用,那么建议一些更具可扩展性、可扩展性和更简洁的东西也无济于事。
【解决方案2】:

为您的消息确定一个分隔符(即确保不会出现在消息中的字符),然后传入一个字符串,其中消息由该字符分隔,例如如果您选择|,则传入$bob-&gt;setParameter('', 'message', "Hi|It's Bob|How are you?");,然后在要与libxslt 一起使用的XSLT 代码中使用例如

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0"
  xmlns:str="http://exslt.org/strings"  
  exclude-result-prefixes="str">

<xsl:param name="message"/>

<xsl:variable name="msgs-rtf">
  <messages>
    <xsl:for-each select="str:tokenize($message, '|')">
       <message>
         <xsl:value-of select="."/>
       </message>
    </xsl:for-each>
  </messages>
</xsl:variable>

<xsl:template match="/">
  <xsl:copy-of select="$msgs-rtf"/>
</xsl:template>

</xsl:stylesheet>

据我所知,libxslt 支持扩展函数str:tokenize,PHP 5 用于 XSLT,因此您应该能够使用它。或者您需要编写一个模板,在 XSLT 本身中进行标记化

【讨论】:

  • 也谢谢你!我马上试试这个:)
【解决方案3】:

PHP 中的串联怎么样?

$bob->setParameter("", "message", "Hi:it's bob:How are you ?");

XSLT 代码中的标记化:

<messages>
<xsl:for-each select="tokenize($message,':')">
<message>
<xsl:value-of select="." />
</message>
</xsl:for-each>
</messages>

【讨论】:

    猜你喜欢
    • 2021-04-18
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多