【问题标题】:Replace new line char with <br /> XSL用 <br /> XSL 替换新行字符
【发布时间】:2011-05-15 16:12:55
【问题描述】:

我有一个 Sharepoint 列表,我想通过 XSL 数据视图将其转换为 JSON。

我有一个 XSL 递归替换函数,用于替换所有特殊字符(转义反斜杠、双引号到 " 等),它为我提供了很好的干净 JSON,可以在用户浏览器中正确解析。

我需要转义/替换的最后一件事是换行符。新行会导致在某些浏览器中解析 JSON 时出错。

这里有一些 xsl 测试标题的内容是否有一个新行字符,如果有,我们输出一个段落:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">

    <xsl:for-each select="catalog/cd">

        <xsl:if test='contains(title,"&#xA;")'>   
                <p>Found <xsl:value-of select="title" /></p>
        </xsl:if>

    </xsl:for-each>

</xsl:template>
</xsl:stylesheet>

这里是一些示例 xml:

<catalog>
    <cd>
        <title>Empire 
Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
    <cd>
        <title>Greatest Hits</title>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>
</catalog>

“帝国滑稽剧”应该是唯一通过测试的项目,但是三个标题都通过了if语句并被输出。

编辑

修改下面的解决方案,如果我想在单个节点上进行搜索和替换,我认为这应该可以工作?直到明天我才能在 Sharepoint 中对其进行测试。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
  <xsl:for-each select="catalog/cd">

  <xsl:variable name="title_clean">
    <xsl:call-template name="repNL">
      <xsl:with-param name="pText" select="title"/>
    </xsl:call-template>
  </xsl:variable>

  <p><xsl:value-of select='$title_clean' /></p>

  </xsl:for-each>
</xsl:template>


<xsl:template name="repNL">
  <xsl:param name="pText" select="."/>

  <xsl:copy-of select="substring-before(concat($pText,'&#xA;'),'&#xA;')"/>

  <xsl:if test="contains($pText, '&#xA;')">
  <br />
  <xsl:call-template name="repNL">
  <xsl:with-param name="pText" select=
  "substring-after($pText, '&#xA;')"/>
  </xsl:call-template>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

【问题讨论】:

  • 无法使用提供的输入进行复制。对于示例 XML 和您的示例 XSLT,它仅匹配“Empire Burlesque”标题。我没有在输出中得到所有三个标题。您确定示例 XML 与您的实际数据匹配吗?
  • 好问题,+1。请参阅我的答案以获得完整、简短且简单的解决方案和详细说明。
  • 结果可以复制到w3schools.com/xsl/…

标签: sharepoint xslt dataview


【解决方案1】:

“帝国滑稽剧”应该是唯一的 项目通过测试,但所有三个 标题通过 if 语句并且是 输出。

无法重现所谓的问题——使用 9 种不同的 XSLT 处理器进行了测试,包括所有来自 Microsoft 的处理器。

无论如何:

此转换将文本节点中的任何 NL 字符替换为 br 元素

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" 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()" name="repNL">
  <xsl:param name="pText" select="."/>

  <xsl:copy-of select=
  "substring-before(concat($pText,'&#xA;'),'&#xA;')"/>

  <xsl:if test="contains($pText, '&#xA;')">
   <br />
   <xsl:call-template name="repNL">
    <xsl:with-param name="pText" select=
    "substring-after($pText, '&#xA;')"/>
   </xsl:call-template>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

应用于以下 XML 文档时(提供的文档添加了 cd 以使其更有趣):

<catalog>
    <cd>
        <title>Line1
        Line2
        Line3
        </title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Empire
        Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
    <cd>
        <title>Greatest Hits</title>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>
</catalog>

产生想要的正确结果

<catalog>
   <cd>
      <title>Line1<br/>     Line2<br/>      Line3<br/>      
      </title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Empire<br/>        Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Hide your heart</title>
      <artist>Bonnie Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title>Greatest Hits</title>
      <artist>Dolly Parton</artist>
      <country>USA</country>
      <company>RCA</company>
      <price>9.90</price>
      <year>1982</year>
   </cd>
</catalog>

解释

  1. 身份规则/模板“按原样”复制每个节点。

  2. 匹配任何文本节点(也称为“repNL”)的覆盖模板执行以下处理:

  3. 使用标记(附加到字符串的 NL 字符),将第一个 NL 字符之前的子字符串(或完整的字符串,如果不包含 NL 字符)复制到输出。

  4. 如果确实包含 NL 字符,则会生成一个 br 元素,并且模板会递归调用自身以获取该 NL 字符之后的剩余字符串。

【讨论】:

    【解决方案2】:

    如果您使用 XslCompiledTransform(C#),相信您使用以下 API 转换 XML 时会遇到问题:
    XslCompiledTransform.Transform(XmlReader input, XmlWriter results)

    但是,以下 API 运行良好:
    XslCompiledTransform.Transform(string, string);
    这是有线的,但我不明白为什么......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      • 2022-08-07
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多