0

式言語を使用してJSPを作成するXSLファイルの要求属性に基づいて、xPathを動的にする必要があります。だから今私はこれを持っています:

<xsl:variable name="xPath">@name='${categoryName}'</xsl:variable>
<xsl:for-each select="tar:products/category[$xPath]/subcategory">

しかし、これは機能しません。したがって、問題は、この問題を回避してxPathを機能させる方法です。


入力XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tar:products SYSTEM "products.dtd" >
<?xml-stylesheet type='text/xsl' href='products2HTML.xsl'?>
<tar:products xmlns:tar="http://www.epam.com/products"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.epam.com/products products.xsd ">
<category name="Electronics">
    <subcategory name="mp3">
        <product name="iPod 4g">
            <provider>Apple</provider>
            <model>Qd246</model>
            <dateOfIssue>11-11-2012</dateOfIssue>
            <color>white</color>
            <notInStock/>
        </product>
        <product name="Cowon">
            <provider>Cowon</provider>
            <model>sF223</model>
            <dateOfIssue>13-12-2012</dateOfIssue>
            <color>black</color>
            <price>13456</price>
        </product>
        <product name="IRiver">
            <provider>IRiver e30</provider>
            <model>Ir234</model>
            <dateOfIssue>13-12-2012</dateOfIssue>
            <color>black</color>
            <price>13456</price>
        </product>
    </subcategory>
    <subcategory name="Computers">
        <product name="iMac">
            <provider>Apple</provider>
            <model>Mm232</model>
            <dateOfIssue>20-02-2012</dateOfIssue>
            <color>silver</color>
            <notInStock/>
        </product>
        <product name="PC">
            <provider>Acer</provider>
            <model>Ae135</model>
            <dateOfIssue>22-11-2012</dateOfIssue>
            <color>black</color>
            <price>13456</price>
        </product>
    </subcategory>
</category>
<category name="Toys">
    <subcategory name="Electronical toys">
        <product name="Cat">
            <provider>UrkToy</provider>
            <model>cC246</model>
            <dateOfIssue>11-11-2012</dateOfIssue>
            <color>grey</color>
            <price>1100</price>
        </product>
        <product name="Dog">
            <provider>LatToy</provider>
            <model>Ld223</model>
            <dateOfIssue>03-12-2012</dateOfIssue>
            <color>white</color>
            <price>13456</price>
        </product>
    </subcategory>
    <subcategory name="Fabric toys">
        <product name="Bear">
            <provider>RusToy</provider>
            <model>BB122</model>
            <dateOfIssue>20-02-2012</dateOfIssue>
            <color>brown</color>
            <notInStock/>
        </product>
        <product name="Bird">
            <provider>BelToy</provider>
            <model>Bb110</model>
            <dateOfIssue>05-11-2012</dateOfIssue>
            <color>red</color>
            <price>500</price>
        </product>
    </subcategory>
</category>
</tar:products>

前のページからのリクエストにパラメータを入れcategoryNameましたが、ページに正常に表示されているので、問題はありません。xslファイルに関する詳細は次のとおりです。

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:tar="http://www.epam.com/products"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.epam.com/products products.xsd ">
<xsl:output method="html" />
<xsl:param name="categoryName" select="'${categoryName}'"></xsl:param>
<xsl:template match="/">
    <table border="1">
        <tr bgcolor="#CCCCCC">
            <td align="center">
                <strong>
                    Subcategories
                            </strong>
            </td>
        </tr>
        <xsl:value-of select="$categoryName"/><!-- this string works -->
        <xsl:for-each select="tar:products/category[@name=$categoryName]/subcategory">
            <xsl:sort order="descending" select="count(product)"
                data-type="number" />
            <a href="controller?command=products&amp;name={@name}">
            <tr bgcolor="#F5F5F5">
                <td>
                    <xsl:value-of select="@name" />
                    (
                    <xsl:value-of select="count(product)" />
                    )
                </td>

            </tr>
            </a>
        </xsl:for-each>
    </table>
    <form method="post" action="/controller?command=back">
        <input type="submit" value="Back"/>
    </form>
</xsl:template>
 </xsl:stylesheet>

リクエストパラメータが次の場合に期待されるcategoryName出力'Toys'

ここに画像の説明を入力してください


実際の出力:

ここに画像の説明を入力してください


RESOVLED

私のJavaクラスでは、変換前にパラメーターをリクエストに入れましたが、単にそれをトランスフォーマーパラメーターに入れる必要がありました。

transformer.setParameter("categoryName", name);
4

3 に答える 3

2

XPath を動的に構築する必要がある場合は、拡張機能を使用する必要があります。たとえば、 EXSTL Dynamic Extension Functionを使用できる場合があります。

ただし、かなり簡潔なコードサンプルを見ると、この場合に余分な複雑さが必要かどうかはわかりません。2行を次のように簡略化できますか:

<xsl:for-each select="tar:products/category[@name=$categoryName]/subcategory">
于 2012-06-20T06:26:40.213 に答える
2

一般的に、それはできません。ただし、ベンダー固有のソリューションがあります。

  1. Tim の EXSLT への言及は完全に正しいです。(dyn:評価())
  2. XALAN には評価機能があります (参照: XSLT での動的 xpath の使用)
  3. Saxon には評価機能があります ( http://saxon.sourceforge.net/saxon7.9/extensions.html#evaluate )

Dimitre の回答も参照してください: dynamic xpath in xslt?

また、XSLT 3.0 には evaluate() 関数 ( http://www.w3.org/TR/xslt-21/#element-evaluate )があることに注意してください。

最後に、評価される動的 XPATH が非常に単純な形式 (例: / 演算子で区切られた用語、軸や述語なし) になるように制約されている場合、名前付きテンプレートを記述して実行することが可能になります。動的 XPATH 評価。しかしもちろん、このテンプレートがどのように見えるかは、式に対する単純な制約に大きく依存します。

例:

サンプルの動的パスを取得します。

<xsl:variable name="xPath">@name='${categoryName}'</xsl:variable>

属性名の部分 (このサンプルでは「名前」) と値の部分 ( ${categoryName} ではなく $categoryName を意味していたと思います) が両方とも変数であると仮定しますが、全体的な形式は他の式、つまり: @some- name='some-string-value' は固定です。次に、次のようにパス式を解決できます。

<xsl:variable name="name" select="'name'" /><!-- or use another computed value. -->
<xsl:variable name="value" select="'my-category-name'" /><!-- or use another computed value. -->
<xsl:for-each select="tar:products/category[@*[name()=$name][.=$value]]/subcategory">
于 2012-06-20T07:41:49.323 に答える
1

要件が「架空の」コード (つまり、XSLT ではない言語で記述されたコード) で記述されているという質問に答えることは常に困難です。したがって、この回答は、あなたがやろうとしていることを私が正しく想像していることを前提としています。その場合は、次のように置き換えます。

<xsl:variable name="xPath">@name='${categoryName}'</xsl:variable>
<xsl:for-each select="tar:products/category[$xPath]/subcategory">

これで:

<xsl:for-each select="tar:products/category[@name = $categoryName]/subcategory">

より一般的な問題として、XSLT には文字列から動的に XPath 式を生成する標準機能がありません。しかし、多くの製品はこれを実現するための拡張関数を提供しています: たとえば、saxon:evaluate() を参照してください。

于 2012-06-20T07:56:37.993 に答える