我正在使用基于this答案的样式表来试验XSLT2:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="source/text()">
<xsl:sequence select="replace(., '<.*?>', '<ph>$0</ph>')"/>
</xsl:template>
</xsl:stylesheet>
旨在进行多次替换,例如:
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
<file>
<source>abc <field1> def <field2> ghi</source>
</file>
</xliff>
为:
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
<file>
<source>abc <ph><field1></ph> def <ph><field2></ph> ghi</source>
</file>
</xliff>
但是我的转换无效,我收到此错误:
Error on line 12 column 54 of my.xsl:
SXXP0003: Error reported by XML parser: The value of attribute "select" associated with an
element type "null" must not contain the '<' character.
如果我使用select="replace(., '<(.*?)>', '<ph>F</phgt;')"
,那么我会在输出中获得...<ph>...
。
如果我使用DOE我会引入其他问题,因为我可能还有其他实体,我想保持不变。如果我使用<xsl:output method="text"/>
我丢失了大部分xml - 还有其他一些“混合和匹配”的方式吗?
答案 0 :(得分:4)
问题在于:
<xsl:sequence select="replace(., '<(.*?)>', '<ph>F</ph>')"/>
格式良好的XML文档不能在属性值中包含<
字符。
在这种特殊情况下,上面的select
属性包含子字符串<ph>F</ph>
,这会导致样式表甚至不被解析为XML文档。
更重要的是,元素不能仅通过字符串替换生成 - 结果将只是字符串(包含编码元素表示) - 而不是元素。
以下是如何实现您的目标:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="source/text()">
<xsl:analyze-string select="." regex="<(.*?)>">
<xsl:matching-substring>
<ph><xsl:value-of select="regex-group(1)"/></ph>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:sequence select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
将此转换应用于提供的XML文档:
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
<file>
<source>abc <field1> def <field2> ghi</source>
</file>
</xliff>
生成了想要的结果:
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
<file>
<source>abc <ph>field1</ph> def <ph>field2</ph> ghi</source>
</file>
</xliff>
解释:正确使用XSLT 2.0说明 <xsl:analyze-string>
, <xsl:matching-substring>
, {{ 3}} 和 <xsl:non-matching-substring>
答案 1 :(得分:1)
如果源文档中出现字符串<
,则文档的XDM树表示将包含字符'&lt;'在它的位置,它将匹配正则表达式'&lt;',它在样式表中写为<
。
所以它应该有效,但你显然做错了什么。告诉我们你做了什么,我们可能有机会告诉你哪里出错了。如果你不告诉我们问题是什么,告诉我们你遇到问题没什么用处。