XSLT transform with source containing < and>

前端 未结 1 1522
无人及你
无人及你 2021-01-22 08:50

I have an input XML in the format below:


   msoft, Version=5.0, Culture=neutral, PublicKeyToken=null
            


        
相关标签:
1条回答
  • 2021-01-22 09:26

    I'll work with the example you provided, and assume it is well-formed. For that I added four extra lines to your source, which is now:

    <Plugins>
        <AssemblyName>msoft, Version=5.0, Culture=neutral, PublicKeyToken=null</AssemblyName>
        <TypeName>BT</TypeName>
        <Version>?</Version>
        <Configuration>
            &lt;AppData xmlns="http://tempuri.org/AppData.xsd"&gt;
              &lt;Readers&gt;
                &lt;Id&gt;1234&lt;/Id&gt;
                &lt;Port&gt;6500&lt;/Port&gt;
                &lt;Type&gt;M200&lt;/Type&gt;
                &lt;Active&gt;Yes&lt;/Active&gt;
              &lt;/Readers&gt;
              &lt;Readers&gt;
              &lt;/Readers&gt;
            &lt;/AppData&gt;
        </Configuration>
    </Plugins>
    

    You will need either an XSLT 2.0 processor or an XSLT 1.0 extension. Here is a solution using XSLT 2.0:

    <xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:tempuri="http://tempuri.org/AppData.xsd"
        exclude-result-prefixes="tempuri"
        version="2.0">
    
        <xsl:output method="xml" indent="yes" use-character-maps="angle-brackets"/>
        <xsl:character-map name="angle-brackets">
            <xsl:output-character character="&lt;" string="&lt;"/>
            <xsl:output-character character="&gt;" string="&gt;"/>
        </xsl:character-map>
    
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="Plugins">
            <xsl:copy>
                <xsl:apply-templates select="Configuration"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="Configuration">
            <xsl:variable name="input">
                <xsl:value-of select="."/>
            </xsl:variable>
            <xsl:apply-templates select="document(concat('data:text/xml,',$input))/tempuri:AppData/tempuri:Readers" />
        </xsl:template>
    
        <xsl:template match="tempuri:Readers">
                <MyReaders>
                    <DeviceId><xsl:value-of select="tempuri:Id"/></DeviceId>
                    <PortNum><xsl:value-of select="tempuri:Port"/></PortNum>
                    <ModelType><xsl:value-of select="tempuri:Type"/></ModelType>
                    <Active><xsl:value-of select="tempuri:Active"/></Active>
                </MyReaders>
        </xsl:template>
    </xsl:stylesheet>
    

    It actually processes your data twice. The angle-brackets inside the contents of Configuration are converted using the character-map. The result is placed inside a variable $input which is converted to a node using the document() function.

    Since your data is in a namespace, it's necessary to prefix the XPath expressions with it. The namespace declaration was removed from the result using exclude-result-prefixes="tempuri".

    0 讨论(0)
提交回复
热议问题