源包含 < 的 XSLT 转换> [英] XSLT transform with source containing < and >
问题描述
我有以下格式的输入 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><AppData xmlns="http://tempuri.org/AppData.xsd">
<Readers>
<Id>1234</Id>
<Port>6500</Port>
<Type>M200</Type>
<Active>Yes</Active>
</Readers>
<Readers>
...
</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>
<AppData xmlns="http://tempuri.org/AppData.xsd">
<Readers>
<Id>1234</Id>
<Port>6500</Port>
<Type>M200</Type>
<Active>Yes</Active>
</Readers>
<Readers>
</Readers>
</AppData>
</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="<" string="<"/>
<xsl:output-character character=">" string=">"/>
</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"
.
这篇关于源包含 &lt; 的 XSLT 转换&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!