源包含 < 的 XSLT 转换> [英] XSLT transform with source containing < and >

查看:27
本文介绍了源包含 < 的 XSLT 转换>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下格式的输入 XML:

I have an input XML in the format below:

<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;
        ...
   </Configuration>
   ...
</Plugins>

我想把它转换成另一种应该像下面这样的 XML,

I want to convert it into another XML which should like the one below,

<Plugins>
   <MyReaders>
       <DeviceId>1234</DeviceId>
       <PortNum>6500</PortNum>
       <ModelType>M200</ModelType>
       <Active>Yes</Active>
   </MyReaders>
</Plugins>

我想使用 XSLT 进行转换.我该怎么做?

I want to use XSLT for conversion. How can I do that?

推荐答案

我将使用您提供的示例,并假设它格式良好.为此,我在您的源代码中添加了四行,现在是:

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>

您将需要 XSLT 2.0 处理器或 XSLT 1.0 扩展.这是使用 XSLT 2.0 的解决方案:

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>

它实际上会处理您的数据两次.Configuration 内容中的尖括号使用 character-map 进行转换.结果放置在变量 $input 中,该变量使用 document() 函数转换为节点.

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.

由于您的数据位于命名空间中,因此有必要在 XPath 表达式前加上它.使用 exclude-result-prefixes="tempuri" 从结果中删除了命名空间声明.

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".

这篇关于源包含 &amp;lt; 的 XSLT 转换&amp;gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆