1

我的场景是我们必须检查元素中的div标签。如果存在,我们必须将文本插入到标签中。cdatabodydivnode2div

这是我的输入 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 节点中有数据,则输出应如下所示:

 <?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很陌生..我只是在学习阶段..你能指导我吗..

4

1 回答 1

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(.,'&lt;div') and contains(.,'&lt;/div>')]">
      <xsl:value-of 
          disable-output-escaping="yes" 
          select="substring-before(.,'&lt;/div')" />
      <xsl:value-of select="../../node2"/>  
      <xsl:value-of 
          disable-output-escaping="yes"
          select="substring-after(.,substring-before(.,'&lt;/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(.,'&lt;div') and contains(.,'&lt;/div>')]">
        <!--get the value of content preceding "</div"-->
        <xsl:value-of 
            disable-output-escaping="yes" 
            select="substring-before(.,'&lt;/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(.,'&lt;/div'))" /> 
    </xsl:template>

    <!--Template for handling body/text() when <abt> does have a value -->
    <xsl:template match="*[normalize-space(abt)]/body/text()[contains(.,'&lt;div') and contains(.,'&lt;/div>')]">
        <!--get the value preceding "<div" -->
        <xsl:value-of 
            disable-output-escaping="yes" 
            select="substring-before(.,'&gt;div')" />
        <xsl:value-of select="../../node2"/>
        <!--get the value following "</div>" -->
        <xsl:value-of 
            disable-output-escaping="yes"
            select="substring-after(.,'&lt;/div>')" /> 
    </xsl:template>
</xsl:stylesheet>
于 2012-12-12T01:25:47.740 回答