实体转换为自定义实体

entity translation to customized entity

提问人:Rahul 提问时间:7/6/2023 更新时间:7/6/2023 访问量:46

问:

xml 数据中有一些用户定义的实体。为了取消对这些实体的转义,我们使用以下代码:-

<xsl:stylesheet version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' >
<xsl:output method="xml" omit-xml-declaration="no" use-character-maps="mdash" />
<xsl:character-map name="mdash">
<xsl:output-character character="&#x2014;" string="&amp;mdash;"/>
<xsl:output-character character="&amp;" string="&amp;amp;" />
<xsl:output-character character="&quot;" string="&amp;quot;" />
<xsl:output-character character="&apos;" string="&amp;apos;" />
<xsl:output-character character="&#167;" string="&amp;sect;"/>
<xsl:output-character character="&#36;" string="&amp;dollar;" />
<xsl:output-character character="&#47;" string="&amp;sol;" />
<xsl:output-character character="&#45;" string="&amp;hyphen;" />
</xsl:character-map>
<!--=================================================================-->
<xsl:template match="@* | node()">
<!--=================================================================-->
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

但是有一种特殊情况,即在数据中出现两次,例如:-&sect;

例如 - 数字 1234&sect;&sect;

上面的示例应该转换为一个特殊的用户定义实体,即

输出 - 数字 1234&multisect;

应转换为&sect;&sect;&multisect;

XSLT XML 解析 Saxon Saxparser XSLT-3.0

评论

0赞 Martin Honnen 7/6/2023
它代表什么,您将如何在 DTD 中声明它?XSLT 的结果是否假定为格式正确的 XML?另外,您使用哪个版本的撒克逊语?商业版有 saxonica.com/html/documentation11/extensions/instructions/...&multisect;&multiselect;
0赞 Rahul 7/6/2023
是,&multiselect;应该是格式正确的 XML。这里我们使用的是 xsl 3.0。

答:

1赞 Michael Kay 7/6/2023 #1

您不能像使用单个字符那样直接在序列化程序中实现此目的。您必须在转换中识别“§§”(也许将其转换为某个专用区域字符,然后由 xsl:output-character 拾取),或者您可以通过在字符流级别对输出进行后处理来做到这一点。

1赞 Martin Honnen 7/6/2023 #2

如果要使用字符映射,首先需要处理文本节点,其中您希望存在两个教派字符,并将它们替换为您不希望在其他地方使用的单个字符;然后,该字符可以通过映射转换为字符串,例如样式表&multisect;

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">
  
  <xsl:param name="multisect-sub" static="yes" as="xs:string" select="'«'"/>
  
  <xsl:character-map name="sub">
    <xsl:output-character _character="{$multisect-sub}" string="&amp;multisect;"/>
  </xsl:character-map>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes" use-character-maps="sub"/>
  
  <xsl:template match="text()">
    <xsl:apply-templates mode="analyze" select="analyze-string(., '&#xA7;&#xA7;')"/>
  </xsl:template>
  
  <xsl:template mode="analyze" match="fn:match">
    <xsl:text>{$multisect-sub}</xsl:text>
  </xsl:template>

</xsl:stylesheet>

转换输入

<!DOCTYPE text [
  <!ENTITY sect "&#xA7;">
]>
<text>&sect;&sect; 1234</text>

进入输出

<?xml version="1.0" encoding="UTF-8"?>
<text>&multisect; 1234</text>

请注意,我主要用作示例,您可能需要使用私有字符或您确定不会出现在输入/输出数据中的其他字符。'«'

如果您希望结果格式正确,您还需要在输出中添加一个文档类型,例如 您确保声明,例如xsl:output doctype-system="some.dtd"some.dtd<!ENTITY multisect "&#xA7;&#xA7;">

评论

0赞 Rahul 7/7/2023
这转化为多切。