使用 XSLT 将 XML 转换为 XML(添加、删除、修改)
Posted
技术标签:
【中文标题】使用 XSLT 将 XML 转换为 XML(添加、删除、修改)【英文标题】:XML to XML conversion with XSLT (Add, delete, modify) 【发布时间】:2012-07-21 08:07:27 【问题描述】:我正在尝试使用 XSLT 从一个 XML (Xhtml) 文件转换为另一个。我必须添加一些新元素和属性,删除一些元素和属性以及更新一些现有属性的值。因此,在本论坛提供的宝贵帮助下,我能够按照我之前的问题的答案完成许多任务:XML to XML with XSLT- Add, Remove, Modify Elements and Attributes 但是当元素具有相同的名称和一个相同的属性时就会出现问题。那时我无法区分它以进行修改。 例如:我在 id="123" 的 div 标签后面有两个 type="t/j" 的脚本,在 head 标签内有一个 type="t/j" 的脚本。我必须删除 src="abc.js" 的脚本元素,仅当它出现在 div 标签之后(不在 head 标签内)并将 xyz.js 的值更改为 lmn.js。 我已经在我的源代码和所需文件中制作了有关修改的 cmets。为了消除 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 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 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 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>
谢谢!
【问题讨论】:
请编辑问题并提供一个尽可能少但完整的示例——而不是真正的 XML 文档。还提供确切的所需结果并解释转换规则。这是为了使问题更容易理解,并增加任何希望花时间阅读、理解和回答的读者的机会。我相信一个不超过 20 行缩进的 XML 文档可以用来表达这个问题。 感谢您的回复。我一定会记住它,实际上我的原始文件很长,所以我试着让它很短,只包含一个部分,但从现在开始我会让它更短。 【参考方案1】:在 90% 的 XSLT 问题中,最大的挑战不是问题的技术方面,而是如何以匹配模式和相应输出的形式表达转换规则。我不会给你一个样式表,而是给你一个问题的模式和输出视图。您应该能够从中制作样式表。不涉及特殊技术。
比较你的输入和输出文件,我将转换规则描述如下。
-
将输入文档复制到输出,但以下情况除外。
在
前面加上以下文字<script type="t/j" src="pqr.js" />
<script type="t/j" src="pqr.js" />
附加到
元素属性 @onload="load()" 和 @onunload="unload()"。 对于任何具有@id=123 的 元素,将@class 更改为QT,将id 更改为456。 对于任何 对于任何将任何具有@class="iD" 的
元素包装在以上是关于使用 XSLT 将 XML 转换为 XML(添加、删除、修改)的主要内容,如果未能解决你的问题,请参考以下文章
WSO2 Enterprise Integrator 6.6.0 使用 XSLT 将 XML 响应转换为 Json