2

メインのxmlドキュメントの属性値を保持するノードを含む外部設定ファイルがあります。属性値が設定ファイルにある場合は、mianxmlファイルからcertianノードを削除する必要があります。

私の設定ファイルは次のようになります。

settings.xml

 <xml>
     <removenode titlename="abc" subtitlename="xyz"></removenode>
     <removenode titlename="dvd" subtitlename="dvd"></removenode>

 </xml>

Main.xml

<xml>
     <title titlename="abc">
         <subtitle subtitlename="xyz"></subtitle>
      </title>
      <title titlename="book">
          <subtitle subtitlename="book sub title"></subtitle>
      </title>
 </xml> 

titlenameとsubtitlenameがmain.xmlで見つかった場合は、setting.xmlファイルを検索し、title要素を削除するスクリプトが必要です。出力は次のようになります

output.xml

 <xml>
      <title titlename="book">
          <subtitle subtitlename="book sub title"></subtitle>
      </title>
 </xml> 

ドキュメントを使用してsetting.xmlファイルを読み取ろうとしましたが、main.xmlファイルで照合を行う方法が見つかりませんでした

 <xsl:variable name="SuppressionSettings" select="document('Setting.xml')" />
    <xsl:variable name="SuppressSetting" select="$SuppressionSettings/xml/removenode" />

それを実装する方法のヒントはありますか?

4

3 に答える 3

2

重要なのは、ID /コピーパターンを使用し、各出力の前に、現在の(コンテキスト)ノードが抑制ルールノードセットによって禁止されていないことを確認することです。

    <!-- get suppression settings -->
    <xsl:variable name='suppression_settings' select="document('http://www.mitya.co.uk/xmlp/settings.xml')/xml/removenode" />


    <!-- begin identity/copy -->

    <xsl:template match="node()|@*">
        <xsl:if test='not($suppression_settings[@titlename = current()/@titlename and @subtitlename = current()/subtitle/@subtitlename])'>
            <xsl:copy>
                <xsl:apply-templates select='node()|@*' />
            </xsl:copy>
        </xsl:if>
    </xsl:template>

ここで実行できます(出力ソースを参照してください-'abc'タイトルノードは省略されています):

http://www.xmlplayground.com/9oCYKp

于 2012-06-15T18:06:46.273 に答える
0

以下に示すこのXSLTは、特定のドキュメントで機能します。

あなたが行ったように、 Setting.xmlの内容を変数に格納していることに注意してください。ただし、その変数をクエリで直接使用します。

ここで重要な問題は、のmatch要素ではtemplate変数を使用できないことです。したがって、私のテンプレートは任意の<title>要素と一致<xsl:choose>し、属性が設定ファイルで指定された値と一致するかどうかを要素で決定します。一致する場合、<title>要素は出力で省略されます。

testのその属性が<xsl:when>本来あるべきことを行う理由の説明として、属性が属性と同じ値でなければならないsomeAttribute = someOtherAttributeという制限としてではなく、任意の2つの属性があり、同じである必要があるという条件としての比較を想像してください。someAttributesomeOtherAttributesomeAttributesomeOtherAttribute

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="SuppressionSettings" select="document('Setting.xml')" />

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

    <xsl:template match="//title">
        <xsl:choose>
            <xsl:when test="(@titlename = $SuppressionSettings/xml/removenode/@titlename) and (subtitle/@subtitlename = $SuppressionSettings/xml/removenode/@subtitlename)"/>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="node()|@*"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>
于 2012-06-15T18:06:57.257 に答える
0

これは、属性の名前がXSLTにハードコードされていない、より一般的な答えです。OR Mapperが指摘したように、XSLT 1.0では、で変数参照を使用できないため、述語に直接match配置します。document()これは、変数を使用してから変数をテストするほど効率的ではない場合があります。

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="*[@* = document('setting.xml')/*/removenode/@*]"/>

</xsl:stylesheet>

XML出力(入力としてmain.xmlを使用して2つのxmlファイルを使用)

<xml>
   <title titlename="book">
      <subtitle subtitlename="book sub title"/>
   </title>
</xml>
于 2012-06-15T18:16:49.653 に答える