0

XSLT を使用して、2 つの個別の web.xml ファイルの要素をマージしようとしています。たとえば、web-1.xml と web-2.xml がマージされていて、web-1.xml を処理している場合、web-2.xml のすべての要素を結果に追加する必要があります。 web-1.xml に既に存在します。

XSLT シートで、次を使用して、サーブレットを他のドキュメントにマージするドキュメントをロードしました。

<xsl:variable name="jandy" select="document('web-2.xml')"/>

次に、次のルールがあります。

<xsl:template match="webapp:web-app">
  <xsl:copy>
    <!--  Copy all of the existing content from the document being processed  -->
    <xsl:apply-templates/>      

    <!--  Merge any <servlet> elements that don't already exist into the result  -->        
    <xsl:for-each select="$jandy/webapp:web-app/webapp:servlet">
      <xsl:variable name="servlet-name"><xsl:value-of select="webapp:servlet-name"/></xsl:variable>

      <xsl:if test="not(/webapp:web-app/webapp:servlet/webapp:servlet-name[text() = $servlet-name])">
        <xsl:copy-of select="."/>
      </xsl:if>
    </xsl:for-each>

  </xsl:copy>

</xsl:template>

私が抱えている問題は、正しい場合にテストを取得することです。上記のコードでは、指定されたノードを持つ servlet-name 要素が存在するかどうかにかかわらず、テストは常に false と評価されます。私はあらゆる種類のさまざまなテストを試しましたが、運がありません。

関連ファイルはhttp://www.cs.hope.edu/~mcfall/stackoverflow/web-1.xmlおよびhttp://www.cs.hope.edu/~mcfall/stackoverflow/transform.xsltで入手できます。 (2 番目の web-2.xml もそこにありますが、StackOverflow では 3 つのリンクを投稿できません)。

4

2 に答える 2

0

webapp:webappテンプレートがからのXPATHと一致し、条件web-1.xmlが次の場合、絶対XPATHを防御しています。相対XPATHを使用してそれを実行してみてください。xsl:if/webapp:web-app/webapp:servlet/webapp:servlet-name[text() = $servlet-name]

  <xsl:if test="not(webapp:servlet/webapp:servlet-name[text() = $servlet-name])">
    <xsl:copy-of select="."/>
  </xsl:if>

まだチェックしていないので、試してみてください。

また、web-1.xmlファイルとweb-2.xmlファイルを提供できれば簡単です。

編集

次のXSLTは、2つのファイルをマージします。唯一の問題は、入力XMLの2つの場所に同じタイプのセクション(リスナーなど)がある場合に発生します。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:webapp="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xpath-default-namespace="http://java.sun.com/xml/ns/javaee">

    <xsl:output indent="yes"/>
    <xsl:variable name="jandy" select="document('web-2.xml')"/>
    <xsl:template match="/">
        <xsl:element name="web-app">
            <xsl:for-each select="webapp:web-app/*[(name() != preceding-sibling::node()[1]/name()) or (position() = 1)]">
                <xsl:variable name="nodeName" select="./name()"/>
                <xsl:variable name="web1" as="node()*">
                    <xsl:sequence select="/webapp:web-app/*[name()=$nodeName]"/>
                </xsl:variable>
                <xsl:variable name="web2" as="node()*">
                    <xsl:sequence select="$jandy/webapp:web-app/*[name() = $nodeName]"/>
                </xsl:variable>
                <xsl:copy-of select="$web1" copy-namespaces="no"/>
                <xsl:for-each select="$web2">
                    <xsl:variable name="text" select="./*[1]/text()"/>
                    <xsl:if test="count($web1[*[1]/text() = $text]) = 0">
                        <xsl:copy-of select="." copy-namespaces="no"/>
                    </xsl:if>
                </xsl:for-each>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
于 2012-05-31T20:16:53.090 に答える
0

for-each ループの直前に、最初のドキュメントのアンカーを提供します。

<xsl:variable name="var" select="."/>

次に、ifで使用します:

<xsl:if test="not($var/webapp:servlet/webapp:servlet-name[text() = $servlet-name])">
于 2012-05-31T22:03:23.693 に答える