我的方案是,我们必须在div
元素的cdata
中检查body
标记。如果存在div
,我们必须将node2
中的文字插入div
代码。
这是我的输入xml:
<?xml version="1.0" encoding="utf-8"?>
<root>
<node1>abc</node1>
<node2> needs to replace inside cdata div</node2>
<body> <![CDATA[
<p>some text some textabcabcabcabc</p>
<div class="marginBottom_4px">
</div>
<p>some text some textabcabc</P>
]]>
</body>
</root>
输出xml将是:
<?xml version="1.0" encoding="utf-8"?>
<div class="marginBottom_10px">
abc
</div>
<div class="marginBottom_5px">
<p>some text some textabcabcabcabc</p>
<div class="marginBottom_4px">
needs to replace inside cdata div
</div>
<p>some text some textabcabc</P>
</div>
我的转变是:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:value-of disable-output-escaping="yes" select ="$firstnode"/>
<xsl:text disable-output-escaping="yes"><![CDATA[ <div class="marginBottom_10px">
]]>
</xsl:text>
<xsl:value-of disable-output-escaping ="yes" select="root/body"/>
<xsl:text disable-output-escaping="yes"><![CDATA[
</div>
]]>
</xsl:text>
</xsl:template>
<xsl:variable name="firstnode">
<xsl:text disable-output-escaping="yes"><![CDATA[
<div class="marginBottom_10px">
]]>
</xsl:text>
<xsl:value-of disable-output-escaping ="yes" select="root/node1"/>
<xsl:text disable-output-escaping="yes"><![CDATA[
</div>
]]>
</xsl:text>
</xsl:variable>
</xsl:stylesheet>
我能够产生输出。但是我的xml非常复杂,如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<ComplexXML>
<environment>
couple of nodes..
</environment>
<document>
nodes
</document>
<element cd="dsjdhfjk" input="abc.xml" mode="" >
<cd position="1">
<attributes>
<type>dummy text</type>
<title>dummy text</title>
</attributes>
<content>
<node2>
<![CDATA[
needs to replace inside cdata div
]]>
</node2>
<body>
<![CDATA[
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type
specimen book </p>
<div class="marginBottom_4px">
</div>
<p>Lorem Ipsum is simply dummy text of her including versions of Lorem Ipsum. </p>
]]>
</body>
<abt >
<![CDATA[
text from abt node
]]>
</abt>
</content>
</cd>
</element>
</ComplexXML>
在上面的xml中我必须检查abt节点。如果数据在abt节点中,则out应如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<div>
text from abt node
<div class="marginBottom_5px">
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type
specimen book </p>
**<div class="marginBottom_4px">
</div>** I need to remove this div tag and place the node2 content here.
<p>Lorem Ipsum is simply dummy text of her including versions of Lorem Ipsum. </p>
</div>
</div>
很抱歉打扰你..我是xslt的新手......我只是在学习阶段。可以指导我..
答案 0 :(得分:0)
以下XSLT 1.0样式表根据示例输出和注释产生我认为所需输出的内容。它依赖于输入文档的CDATA
中的文本格式正确,并利用disable-output-escaping
:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node1">
<div class="marginBottom_10px">
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="node2" />
<xsl:template match="body">
<div class="marginBottom_5px">
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="body/text()[contains(.,'<div') and contains(.,'</div>')]">
<xsl:value-of
disable-output-escaping="yes"
select="substring-before(.,'</div')" />
<xsl:value-of select="../../node2"/>
<xsl:value-of
disable-output-escaping="yes"
select="substring-after(.,substring-before(.,'</div'))" />
</xsl:template>
</xsl:stylesheet>
当应用示例输入时,产生:
<?xml version="1.0" encoding="UTF-8"?>
<div class="marginBottom_10px">abc</div>
<div class="marginBottom_5px">
<p>some text some textabcabcabcabc</p>
<div class="marginBottom_4px">
needs to replace inside cdata div</div>
<p>some text some textabcabc</P>
</div>
注意:输出格式不正确。没有文档元素。您可能希望为<root>
创建模板以创建<div>
或其他包含元素。
此版本处理其他输入格式并生成我认为所需输出的内容:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<!--rely on built-in templates,
which apply-templates to child nodes of elements
and get value-of for text() -->
<xsl:template match="content">
<xsl:choose>
<!-- if <abt> has a value, do the following -->
<xsl:when test="normalize-space(abt)">
<div>
<!-- apply templates to <abt>,
built-in template will copy text to output-->
<xsl:apply-templates select="abt"/>
<!-- apply templates to <body>, template defined below will handle it -->
<xsl:apply-templates select="body"/>
</div>
</xsl:when>
<xsl:otherwise>
<!--process child nodes -->
<xsl:apply-templates />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="node1">
<div class="marginBottom_10px">
<xsl:apply-templates/>
</div>
</xsl:template>
<!--empty template ensures that no content produced when templates applied to <node2>-->
<xsl:template match="node2" />
<xsl:template match="body">
<div class="marginBottom_5px">
<xsl:apply-templates/>
</div>
</xsl:template>
<!--Template for handling body/text() when <abt> does not have a value-->
<xsl:template match="*[not(normalize-space(abt))]/body/text()[contains(.,'<div') and contains(.,'</div>')]">
<!--get the value of content preceding "</div"-->
<xsl:value-of
disable-output-escaping="yes"
select="substring-before(.,'</div')" />
<!--get the value of <node2> -->
<xsl:value-of select="../../node2"/>
<!--get the value of content starting at "</div" -->
<xsl:value-of
disable-output-escaping="yes"
select="substring-after(.,substring-before(.,'</div'))" />
</xsl:template>
<!--Template for handling body/text() when <abt> does have a value -->
<xsl:template match="*[normalize-space(abt)]/body/text()[contains(.,'<div') and contains(.,'</div>')]">
<!--get the value preceding "<div" -->
<xsl:value-of
disable-output-escaping="yes"
select="substring-before(.,'>div')" />
<xsl:value-of select="../../node2"/>
<!--get the value following "</div>" -->
<xsl:value-of
disable-output-escaping="yes"
select="substring-after(.,'</div>')" />
</xsl:template>
</xsl:stylesheet>