请建议如何根据外部文件根据其中给出的xpath更新元素的名称。
我试过,几乎没有变量来存储来自外部文件的xpath,模板匹配元素的xpath,但是无法获得所需的信息。请建议。
外部文件(FindReplaceElements.ini):
<root>
<tofind>aside/p</tofind> <toreplace><p class="aside_Para"></p></toreplace>
<tofind>aside[@class="sidenote1"]/p</tofind> <toreplace><p class="aside_Para1"></p></toreplace>
<tofind>body/p</tofind> <toreplace><p class="body_Para"></p></toreplace>
<tofind>body/div/div/h1</tofind> <toreplace><p class="body_h_2"></p></toreplace>
<tofind>body/div/div/div/h1</tofind> <toreplace><p class="body_h_3"></p></toreplace>
</root>
输入XML:
<article>
<body>
<p>The body para1</p>
<aside><p>Aside para1</p></aside>
<aside class="sidenote1"><p>Aside para2</p></aside>
<div><div class="special"><h1>The Heading1</h1></div></div>
<div><div><div><h1>The Heading2</h1></div></div></div>
</body>
</article>
必填结果:
<article>
<body>
<p class="body_Para">The body para1</p>
<aside><p class="aside_Para">Aside para1</p></aside>
<aside class="sidenote1"><p class="aside_Para1">Aside para2</p></aside>
<div><div class="special"><p class="body_h_2">The Heading1</p></div></div>
<div><div><div><p class="body_h_3">The Heading2</p></div></div></div>
</body>
</article>
XSLT:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:variable name="varDocElemsIni" select="document('FindReplaceElements.ini')"/>
<xsl:variable name="varDQote">"</xsl:variable>
<xsl:template match="p">
<xsl:variable name="nodeAsStr"><xsl:value-of select="name(.)"/></xsl:variable><!--String name of element -->
<xsl:variable name="varAllMatchedEles"> <!--getting Elements name from INI file-->
<xsl:for-each select="$varDocElemsIni/root/tofind">
<xsl:variable name="varNextElemINI"><xsl:value-of select="following-sibling::*[1]/name()"/></xsl:variable><!--From INI file, required element name-->
<xsl:variable name="varPathINI"><!--xPath of element from INI file-->
<xsl:for-each select="$varDocElemsIni/root/tofind/tokenize(text(), '/')[not(position()=last())]">
<xsl:value-of select="."/><xsl:value-of select="'/'"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="varNameElem1">
<xsl:for-each select="tokenize(text(), '/')[last()]">
<xsl:if test=". = $nodeAsStr">
<xsl:value-of select="$varNextElemINI"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="varPath"><!--xPath of Element from given input file -->
<xsl:value-of select="concat(ancestor::*[2]/name(), '/', parent::*/name())"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$varAllMatchedEles=$varPath">
<xsl:element name="{$varNextElemINI}"><xsl:apply-templates select="@*|node()"/></xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
另外一个XSLT尝试如下:但无法获得结果
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:variable name="varDocElemsIni" select="document('FindReplaceElements.ini')"/>
<xsl:variable name="vardQote">"</xsl:variable>
<xsl:template match="h1">
<xsl:call-template name="TempInsertElemsAttribs"/>
</xsl:template>
<xsl:template match="h2">
<xsl:call-template name="TempInsertElemsAttribs"/>
</xsl:template>
<xsl:template name="TempInsertElemsAttribs">
<xsl:variable name="varReqElemName">
<xsl:for-each select="$varDocElemsIni/root/tofind/*[name()=current()/name()]">
<xsl:value-of select="parent::tofind/following-sibling::*[1][name()='toreplace']/child::*/name()"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="varReqElemNameAttrib">
<xsl:for-each select="$varDocElemsIni/root/tofind/*[name()=current()/name()]/parent::tofind/following-sibling::*[1][name()='toreplace']/child::*/@*">
<xsl:value-of select="concat(name(), '=', $vardQote, ., $vardQote)"/><xsl:if test="not(position()=last())"><xsl:text> </xsl:text></xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="string-length($varReqElemName) gt 0">
<xsl:text disable-output-escaping="yes"><</xsl:text><xsl:value-of select="$varReqElemName"/>
<xsl:if test="string-length($varReqElemNameAttrib) gt 0"><xsl:value-of select="concat(' ', $varReqElemNameAttrib)"/></xsl:if>
<xsl:text disable-output-escaping="yes">></xsl:text>
<xsl:apply-templates/>
<xsl:text disable-output-escaping="yes"></</xsl:text><xsl:value-of select="$varReqElemName"/><xsl:text disable-output-escaping="yes">></xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:2)
我建议你分两步完成:
首先,将以下样式表应用于&#34;外部文件&#34;:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:template match="/root">
<axsl:stylesheet version="2.0">
<axsl:template match="@*|node()">
<axsl:copy>
<axsl:apply-templates select="@*|node()"/>
</axsl:copy>
</axsl:template>
<xsl:apply-templates select="tofind"/>
</axsl:stylesheet>
</xsl:template>
<xsl:template match="tofind">
<axsl:template match="{.}">
<xsl:apply-templates select="following-sibling::toreplace[1]/*"/>
</axsl:template>
</xsl:template>
<xsl:template match="toreplace/*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<axsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您的示例中的结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="aside/p">
<p class="aside_Para">
<xsl:apply-templates select="@*|node()"/>
</p>
</xsl:template>
<xsl:template match="aside[@class="sidenote1"]/p">
<p class="aside_Para1">
<xsl:apply-templates select="@*|node()"/>
</p>
</xsl:template>
<xsl:template match="body/p">
<p class="body_Para">
<xsl:apply-templates select="@*|node()"/>
</p>
</xsl:template>
<xsl:template match="body/div/div/h1">
<p class="body_h_2">
<xsl:apply-templates select="@*|node()"/>
</p>
</xsl:template>
<xsl:template match="body/div/div/div/h1">
<p class="body_h_3">
<xsl:apply-templates select="@*|node()"/>
</p>
</xsl:template>
</xsl:stylesheet>
这个结果是一个自己的XSLT样式表。应用它您的输入示例将产生以下结果:
<?xml version="1.0" encoding="UTF-8"?><article>
<body>
<p class="body_Para">The body para1</p>
<aside><p class="aside_Para">Aside para1</p></aside>
<aside class="sidenote1"><p class="aside_Para1">Aside para2</p></aside>
<div><div class="special"><p class="body_h_2">The Heading1</p></div></div>
<div><div><div><p class="body_h_3">The Heading2</p></div></div></div>
</body>
</article>
请注意,其中一些规则含糊不清。当您将生成XSLT的过程分配给外部代理时,您可能会遇到危险。