【发布时间】:2016-03-25 13:10:50
【问题描述】:
我有一个 XML,我想使用以下 xslt 将属性值 (name="name") 更改为另一个 (name="value"):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--xsl:template match="text()"-->
<!--xsl:text select="." disable-output-escaping="yes" /-->
<!--xsl:value-of select="." disable-output-escaping="yes" />
<xsl:copy-of select="child::*"/>
</xsl:template-->
<xsl:template match="@*|node()" mode="s">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="s"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()" mode="se">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="se"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@name" mode="se">
<xsl:attribute name="name">value</xsl:attribute>
</xsl:template>
<xsl:template match="tag5[@type='testtype']">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="s"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tag6[@name='name']" mode="s">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="se"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML 输入 sn-p:
<?xml version="1.0" encoding="UTF-8"?>
<dataroot version="2.0">
<Model id="111" name="test">
<tag1 id="222" type="VERSION">
<tag2 id="333" name="Version" value="2"/>
</tag1>
<tag3 id="444">
<tag4 id="555" versionID="test/00001" name="name" definition="through test. 
" attrs="12 23"/>
<tag4 id="666" versionID="test/00001" name="name" definition="through test 2. 
" messages="34 45"/>
</tag3>
<tag5 id="777" type="testtype">
<tag6 id="888" name="name" value="667"/>
<tag6 id="999" name="context" value="FIX 5.0"/>
</tag5>
</Model>
</dataroot>
应用 xslt 后的 XML OUTPUT 为:
<?xml version="1.0" encoding="UTF-8"?>
<dataroot version="2.0">
<Model id="111" name="test">
<tag1 id="222" type="VERSION">
<tag2 id="333" name="Version" value="2"/>
</tag1>
<tag3 id="444">
<tag4 id="555" versionID="test/00001" name="name" definition="through test. " attrs="12 23"/>
<tag4 id="666" versionID="test/00001" name="name" definition="through test 2. " messages="34 45"/>
</tag3>
<tag5 id="777" type="testtype">
<tag6 id="888" name="value" value="667"/>
<tag6 id="999" name="context" value="FIX 5.0"/>
</tag5>
</Model>
</dataroot>
xslt 基本上完成了预期的工作。然而,意外的转变:

 -> (unexpected transform)
我想保留原始实体。 我试过 disable-output-escape (请参阅 xslt 中的注释部分,将文本更改为@definition),不起作用。有什么建议吗?
顺便说一句,我使用 xsltproc。
提前致谢!
【问题讨论】:
-
您不能使用 XSLT 保留字符引用,XSLT 处理器使用 XML 解析器来解析输入,引入具有 Unicode 字符值的节点树,然后使用 Unicode 字符。然后在完成任何必要的转义时对转换结果进行序列化。所以你不能用纯 XSLT 解决这个问题,你需要查看你的特定 XSLT 处理器及其序列化功能是否可以强制使用十六进制字符引用。
-
@MartinHonnen,我使用 xsltproc,有什么提示吗?
-
@delair 它有什么不同?
&amp;#xA;和&#10;都是 equally valid representation of the same character. 你为什么要关心这个? -
@michael.hor257k, XML 文件是一个模型,它是许多其他工具的来源。因此,每个属性都由不同的多个工具处理。我想尽量减少更改以避免意外。
-
任何符合 XML 标准的工具都应该能够平等地处理这两种表示。在任何情况下,您都不能保留原始表示(正如 Martin Honnen 已经解释过的),您只能强制使用一种或另一种表示。在 XSLT 1.0 self 中可以做到这一点,通过用转义字符串(例如
&amp;#xA;)替换字符并使用 DOE 输出这些字符 - 但这是很多工作。