使用 XSLT 修改嵌入其他元素文本中的元素

发布于 2024-11-02 04:21:17 字数 588 浏览 1 评论 0原文

由于我可能会搞乱术语,因此我将通过示例进行解释。

我的 XML 源文档包含如下元素:

<paragraph>
    This paragraph has things like <link><xref label="lbl1">this</xref></link>
    and things like <emphasis type="bold">this</emphasis>
    and <emphasis type="italic">this</emphasis>.
</paragraph>

需要使用 XSLT 将其转换为:

<p>
    This paragraph has things like <a href="[lbl1]">this</a>
    and things like <b>this</b>
    and <i>this</i>.
</p>

谢谢!

Since I would probably botch up the terminology, I'll explain by example.

My XML source document contains elements like this:

<paragraph>
    This paragraph has things like <link><xref label="lbl1">this</xref></link>
    and things like <emphasis type="bold">this</emphasis>
    and <emphasis type="italic">this</emphasis>.
</paragraph>

Need to use XSLT to transform that to:

<p>
    This paragraph has things like <a href="[lbl1]">this</a>
    and things like <b>this</b>
    and <i>this</i>.
</p>

Thanks!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

歌入人心 2024-11-09 04:21:17

当前的两种解决方案太长,其中一种甚至不是格式良好的 XML...

这是一个简短而完整的解决方案

<xsl:stylesheet version="1.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="link">
  <a href="[{xref/@label}]">
   <xsl:apply-templates/>
  </a>
 </xsl:template>

 <xsl:template match="emphasis">
  <xsl:element name="{substring(@type,1,1)}">
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>
 <xsl:template match="xref">
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<paragraph>This paragraph has things like <link><xref label="lbl1">this</xref></link> and things like <emphasis type="bold">this</emphasis> and <emphasis type="italic">this</emphasis>.
</paragraph>

产生了想要的正确结果

<paragraph>This paragraph has things like <a href="[lbl1]">this</a> and things like <b>this</b> and <i>this</i>.
</paragraph>

The current two solutions are too-long and one of them is not even well-formed XML...

Here is a short and complete solution:

<xsl:stylesheet version="1.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="link">
  <a href="[{xref/@label}]">
   <xsl:apply-templates/>
  </a>
 </xsl:template>

 <xsl:template match="emphasis">
  <xsl:element name="{substring(@type,1,1)}">
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>
 <xsl:template match="xref">
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document:

<paragraph>This paragraph has things like <link><xref label="lbl1">this</xref></link> and things like <emphasis type="bold">this</emphasis> and <emphasis type="italic">this</emphasis>.
</paragraph>

the wanted, correct result is produced:

<paragraph>This paragraph has things like <a href="[lbl1]">this</a> and things like <b>this</b> and <i>this</i>.
</paragraph>
梦萦几度 2024-11-09 04:21:17

这应该可以解决问题:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

  <xsl:output method="xml" indent="yes" />

  <xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="paragraph">
    <xsl:element name="p">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>

  <xsl:template match="link">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="xref">
    <xsl:element name="a">
      <xsl:attribute name="href">
        <xsl:text>[</xsl:text><xsl:value-of select="@label" /><xsl:text>]</xsl:text>
      </xsl:attribute>
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>

  <xsl:template match="emphasis">
    <xsl:variable name="elementName">
      <xsl:choose>
        <xsl:when test="@type='bold'">
          <xsl:text>b</xsl:text>
        </xsl:when>
        <xsl:when test="@type='italic'">
          <xsl:text>i</xsl:text>
        </xsl:when>
      </xsl:choose>    
    </xsl:variable>
    <xsl:if test="string-length($elementName)>0">
      <xsl:element name="{$elementName}">
        <xsl:apply-templates />
      </xsl:element>
    </xsl:if>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

This should do the trick:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

  <xsl:output method="xml" indent="yes" />

  <xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="paragraph">
    <xsl:element name="p">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>

  <xsl:template match="link">
    <xsl:apply-templates />
  </xsl:template>

  <xsl:template match="xref">
    <xsl:element name="a">
      <xsl:attribute name="href">
        <xsl:text>[</xsl:text><xsl:value-of select="@label" /><xsl:text>]</xsl:text>
      </xsl:attribute>
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>

  <xsl:template match="emphasis">
    <xsl:variable name="elementName">
      <xsl:choose>
        <xsl:when test="@type='bold'">
          <xsl:text>b</xsl:text>
        </xsl:when>
        <xsl:when test="@type='italic'">
          <xsl:text>i</xsl:text>
        </xsl:when>
      </xsl:choose>    
    </xsl:variable>
    <xsl:if test="string-length($elementName)>0">
      <xsl:element name="{$elementName}">
        <xsl:apply-templates />
      </xsl:element>
    </xsl:if>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文