1

XSLT を使用して、ある XML (XHTML) ファイルから別のファイルに変換しようとしています。いくつかの新しい要素と属性を追加し、いくつかの要素と属性を削除し、いくつかの既存の属性の値を更新する必要があります。そのため、このフォーラムで提供された貴重な支援により、以前の質問「 XSLT を使用した XML から XML への XML - 要素と属性の追加、削除、変更」の回答に従って、多くのタスクを実行できます。しかし、要素が同じ名前と 1 つの同じ属性を持つ場合に問題が発生します。その時点で、私はそれを区別して変更することができません。例: id="123" の div タグの後に type="t/j" の 2 つのスクリプトがあり、head タグ内に type="t/j" のスクリプトが 1 つあります。src="abc.js" のスクリプト要素を削除する必要があります。これは、div タグの後に表示される場合にのみ (head タグ内ではなく)、xyz.js の値を lmn.js に変更する必要があります。修正に関して、ソースと希望のファイルにコメントしました。onClick イベントを排除するために、@onClick を使用して何もしないテンプレート マッチを渡し、要件に従ってどこからでも onClick イベントを削除しています。ただし、「スパン」を削除するために同じ手法を適用すると 特定の場所(ソースファイルでコメントされている)からタグを付けると、そこから削除されるだけでなく、望まない他のすべての場所からも削除されます。以下の XML ファイルを見つけてください。

ソースファイル:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-type" content="text/html;  charset=utf-8" />
<script type="t/j" src="abc.js"></script>
</head>

<body>
<div id="o">
<div id="m">
<div id="nD">
<p id="nT">
Part 1</p>
</div>

<div class="TF" id="123">
<!--CHANGE THE VALUE OF XYZ.JS TO LMN.JS-->
<script type="t/j" src="xyz.js"></script>
<!--REMOVE THIS SCRIPT-->
<script type="t/j" src="abc.js"></script>
<div class="iD">
<img alt="" src="ic.gif" />
<span class="iDe">ABC</span><br/>
<div class="iDev">
<div id="ta12" class="bl" style="dis:bl"></div>

<div class="q">
<br/><br/>
<!--TO REMOVE SPAN TAG FROM HERE-->
<div id="ta12" class="bl" style="dis:bl">1<span style="color: #000000;"> XYZ</span> </div>
<!--REMOVE ONCLICK EVENT -->
<br/>T <input type="radio" name="op12" id="t12" onclick="getFeedback()"/> 
F <input type="radio" name="op12" id="f12" onclick="getFeedback()"/>
<div>C </div>
<div>In </div>

<div>
<div></div>
</div>
</div>

</div>
</div>
</div>

</div>
</div>
</body></html>

目的のファイル:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;  charset=utf-8" />
<script type="t/j" src="abc.js"></script>
</head>

<script type="t/j" src="pqr.js"></script>
<script type="t/j" src="stu.js"></script>

<body onload="load()" onunload="unload()">
<div id="o">
<div id="m">
<div id="nD">
<p id="nT">
Part 1</p></div>

<div class="QT" id="456">
<script type="t/j" src="lmn.js"></script>
<form name="form1" id="q8" action="js:cal();">
<div class="iD">
<img alt="" src="ic.gif" />
<span class="iDe">ABC</span>
<div class="iDev">
<!--ADD THIS DIV TAG-->
<div class="pa" value="10"></div>

<div class="q">
<div id="ta8" class="bl" style="dis:bl">XYZ 
</div><br/>
<input type="radio" name="ke8" value="0" />
<div id="tab8" class="bl" style="dis:bl">T 
</div>
<input type="radio" name="ke8" value="1" />
<div id="tab8" class="bl" style="dis:bl">F 
</div>
</div>
<br/><input type="submit" name="sub" value="Done"/>
</div></div>
</form>
</div>
</div>
</div>

</body></html>

XSLT 1.0 を使用しています。したがって、提案といくつかの変更に従って(id="1" のような場所では異なりますが)、私の XSLT は次のようになります

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xhtml="http://www.w3.org/1999/xhtml"
 xmlns="http://www.w3.org/1999/xhtml"
 exclude-result-prefixes="xhtml">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*" />

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

<xsl:template match="xhtml:body">
<script type="t/j" src="pqr.js"></script>
<script type="t/j" src="stu.js"></script>
<body onload="loadPage()" onunload="unloadPage()">
  <xsl:apply-templates select="@*|node()"/>
</body>
</xsl:template>
<xsl:template match="xhtml:div[@id='123']/@class">
  <xsl:attribute name="class">QT</xsl:attribute>
   <xsl:attribute name="id">456</xsl:attribute> 
</xsl:template>
<xsl:template match="xhtml:script[@src='xyz.js']">
 <xsl:copy>
  <xsl:apply-templates select="@*[not(@src)]" />
  <xsl:attribute name="src">lmn.js</xsl:attribute>
  <xsl:apply-templates select="node()" />
 </xsl:copy>
</xsl:template>
<xsl:template match="xhtml:body//xhtml:script[@src='abc.js']" />

<xsl:template match="xhtml:div[@class='iD']">
  <form name="form">
   <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
   <xsl:apply-templates select="following-sibling::xhtml:div[1]" mode="inside-form"/>
   <br/><input type="submit" name="sub" value="Done"/> 
  </form>
</xsl:template>
<xsl:template match="xhtml:div[@id='ta12']">
  <xsl:attribute name="class">pa</xsl:attribute>
  <xsl:attribute name="value">10</xsl:attribute>
</xsl:template>

<xsl:template match="xhtml:div[@class='iDev']">
   <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
     <div id="ta8" class="bl" style="dis:bl">XYZ</div>
<br/>
   <input type="radio" name="ke8" value="0" />
<div id="tab8" class="bl" style="dis:bl">T</div>
   <input type="radio" name="ke8" value="1" />
<div id="tab8" class="bl" style="dis:bl">F</div>
</xsl:template>

</xsl:stylesheet>

私が得ている出力-

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-type" content="text/html;  charset=utf-8"/>
<script type="t/j" src="abc.js" xml:space="preserve"/>
</head>
<script type="t/j" src="pqr.js"/>
<script type="t/j" src="stu.js"/>
<body onload="loadPage()" onunload="unloadPage()">
<div id="o">
<div id="m">
<div id="nD">
<p id="nT">
Part 1</p>
</div>
<!--VALUE OF CLASS HAS CHANGED BUT NOT ID-->
<div class="QT" id="123">
<script type="t/j" src="lmn.js" xml:space="preserve"/>
<form name="form">
<div class="iD">
<img alt="" src="ic.gif"/>
<span class="iDe">ABC</span>
<br clear="none"/>
<!--DIV TAG WITH CLASS=IDEV IS MISSING-->
<div class="pa" value="10">
<div class="q">
<!--BR HAVE APPEARED WITH ATTRIBUTE CLEAR-->
<br clear="none"/>
<br clear="none"/>
<!--INPUT TAGS HAVE APPEARED TWICE-->
<br clear="none"/>T <input type="radio" name="op12" id="t12" onclick="getFeedback()"/> 
F <input type="radio" name="op12" id="f12" onclick="getFeedback()"/>
<div>C </div>
<div>In </div>
<div>
<div/>
</div>
</div>
</div>
<div id="ta8" class="bl" style="dis:bl">XYZ</div>
<br/>
<input type="radio" name="ke8" value="0"/>
<div id="tab8" class="bl" style="dis:bl">T</div>
<input type="radio" name="ke8" value="1"/>
<div id="tab8" class="bl" style="dis:bl">F</div>
</div>
<br/>
<input type="submit" name="sub" value="Done"/>
</form>
</div>
</div>
</div>
</body>
</html>

ありがとうございます!

4

1 に答える 1

1

XSLTの質問の90%で、最大の課題は、質問の技術的な側面ではなく、一致パターンと対応する出力の形で変換のルールを明確にする方法です。スタイルシートを提供するのではなく、質問のパターンと出力ビューを提供します。これからスタイルシートを作成できるはずです。特別なテクニックは必要ありません。

入力ドキュメントと出力ドキュメントを比較して、変換のルールを次のように説明します。

  1. 次の例外を除いて、入力ドキュメントを出力にコピーします。
  2. <body>の前に次のリテラルを付けます

    <script type="t/j" src="pqr.js" />
    <script type="t/j" src="pqr.js" />
    
  3. <body>要素の属性@onload="load()"および@onunload = "unload()"に追加します。

  4. @ id = 123を持つ<div>要素の場合、@ classをQTに、idを456に変更します。
  5. <script>要素の場合は、@ src="xyz.js"を"lmn.js"に変更します。
  6. @ src = "abc.js"を含む本文の<script>要素については、削除してください。
  7. @ class = "iD"を含む<div>要素を<form>でラップし、フォームを閉じる直前に、次のリテラルを含めます

    <br/><input type="submit" name="sub" value="Done"/>
    
  8. <div>要素を@id= "ta12"に置き換えて、次のように置き換えます。

    <div id="pa" value="10" />
    
  9. <div class = "iDev">をコピーします。ただし、その子を次のリテラルに置き換えます。

    <div id="ta8" class="bl" style="dis:bl">XYZ</div>
    <br/>
    <input type="radio" name="ke8" value="0" />
    <div id="tab8" class="bl" style="dis:bl">T</div>
    <input type="radio" name="ke8" value="1" />
    <div id="tab8" class="bl" style="dis:bl">F</div>
    

アップデート

OPはポイント5のテンプレートを要求しました。これがここにあります。これは、1つの属性を変更するだけで、ノードをコピーする方法に関する一般的なソリューションです...

<xsl:template match="xhtml:script[@src='xyz.js']">
 <xsl:copy>
  <xsl:apply-templates select="@*[not(@src)]" />
  <xsl:attribute name="src">lmn.js</xsl:attribute>
  <xsl:apply-templates select="node()" />
 </xsl:copy>
</xsl:template>

あまり一般的でない解決策を使用してもかまわず、スクリプト要素に子がなく、他の属性が1つだけであると想定できる場合は、たとえば、より簡潔で具体的なテンプレートを使用できます。そのように(しかし、私はそれをお勧めしません-私はあなたのオプションをレイアウトしているだけです...

<xsl:template match="xhtml:script[@src='xyz.js']">
 <xhtml:script type="t/j" src="lmn.js" />
</xsl:template>

そしてポイント6の場合は...

<xsl:template match="xhtml:body//xhtml:script[@src='abc.js']" />
于 2012-07-23T06:00:19.577 に答える