【问题标题】:Converting XAML to XHTML using XSLT使用 XSLT 将 XAML 转换为 XHTML
【发布时间】:2013-05-20 11:24:53
【问题描述】:

我需要使用 XSLT 将 X(A)ML 转换为 XHTML。

以下是 XAML 输入数据:

<Section>
  <Paragraph>
    <Span Text="plain 1 " />
    <Span Text="bold" FontWeight="bold" />
    <Span Text=" plain 2 " />
    <Span Text="italic" FontStyle="italic" />
    <Span Text=" plain3 " />
    <Span Text="underline" UnderlineDecoration="line" />
    <Span Text="Bold" FontWeight="bold" />
  </Paragraph>
  <Paragraph>
    <Span Text="plain " />
    <Span Text="Italic" FontStyle="italic" />
    <Span Text=" plain " />
  </Paragraph>
  <Paragraph>
    <Span Text="BoldItalic" FontWeight="bold" FontStyle="italic" />
  </Paragraph>
  <Paragraph>
    <Span Text="plain " />
    <Span Text=" Bold " FontWeight="bold" />
    <Span Text=" BoldItalic " FontWeight="bold" FontStyle="italic" />
    <Span Text=" BoldItalicUnderline " FontWeight="bold" FontStyle="italic" UnderlineDecoration="line" />
    <Span Text=" BoldItalic " FontWeight="bold" FontStyle="italic" />
    <Span Text=" Bold " FontWeight="bold" />
    <Span Text=" plain " />
  </Paragraph>
  <Paragraph>
    <Span Text="plain " />
    <Span Text="BoldItalicUnderline " FontWeight="bold" FontStyle="italic" UnderlineDecoration="line" />
    <Span Text=" plain " />
  </Paragraph>
  <Paragraph>
    <Span Text="plain " />
    <Span Text="Bold " FontWeight="bold" />
    <Span Text=" Bold and Italic " FontWeight="bold" FontStyle="italic" />
    <Span Text=" Bold and Italic and Underline " FontWeight="bold" FontStyle="italic" UnderlineDecoration="line" />
    <Span Text=" Bold and Italic " FontWeight="bold" FontStyle="italic" />
    <Span Text=" Bold " FontWeight="bold" />
    <Span Text=" plain " />
  </Paragraph>
</Section>

使用 XSLT 作为输出的预期 XHTML 数据:

<QuestionText xml:space="preserve">
  <p>plain 1 <b>bold</b> plain 2 <i>italic</i> plain3 <u>underline</u><b>Bold</b></p>
  <p>plain <i>Italic</i> plain </p>
  <p><b><i>BoldItalic</i></b></p>
  <p>plain <b> Bold <i> BoldItalic <u> BoldItalicUnderline </u> BoldItalic </i> Bold </b> plain </p>
  <p>plain <b><i><u>BoldItalicUnderline </u></i></b> plain </p>
  <p>plain <b>Bold <i> Bold and Italic <u> Bold and Italic and Underline </u> Bold and Italic </i> Bold </b> plain </p>
</QuestionText>

我不知道如何将所有跨度(兄弟)节点转换为一个父节点。

非常感谢任何有关 XSLT 将上述 XAML 转换为 XHTML 的帮助。

【问题讨论】:

    标签: xml xslt xml-parsing


    【解决方案1】:

    为每个非普通&lt;Span&gt; 设置一个模板,优先级更高:

     match="Span[@FontWeight = 'bold']" priority="2"
    

    等等。内容类似于

     <b><xsl:value-of select="@Text" /></b>
    

    然后有一个模板匹配剩余的&lt;Span&gt;元素,优先级较低:

    match="Span" priority="1"
    

    后者的内容可以是

    <xsl:value-of select="@Text" />
    

    实际上,这些模板的默认优先级是“Span”模板的优先级低于其他模板,大致是因为它不太具体。所以你没有添加priority 属性。但是,如果您明确优先级,您的代码将更具可读性、可预测性和可维护性。

    请注意,对于 XHTML 输出,您必须将 XHTML 命名空间声明为默认输出命名空间,以便上述 &lt;b&gt; 正确。但我假设你已经涵盖了这一点。

    如果您需要有关问题的样式组合方面的帮助(同时斜体、粗体、下划线),请告诉我。

    更新

    针对关于样式组合的评论,这是一个样式表:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0">
    
      <xsl:template match="Section">
        <QuestionText xml:space="preserve">
          <xsl:apply-templates />
        </QuestionText>
      </xsl:template>
    
      <xsl:template match="Paragraph">
        <p><xsl:apply-templates select="*" /></p>  
      </xsl:template>
    
      <xsl:template match="Span">
        <xsl:variable name="bold">
          <xsl:choose>
            <xsl:when test="@FontWeight='bold'"><b><xsl:value-of select="@Text"/></b></xsl:when>
            <xsl:otherwise><xsl:value-of select="@Text"/></xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:variable name="italic">
          <xsl:choose>
            <xsl:when test="@FontStyle='italic'"><i><xsl:copy-of select="$bold"/></i></xsl:when>
            <xsl:otherwise><xsl:copy-of select="$bold"/></xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        <xsl:choose>
          <xsl:when test="@UnderlineDecoration='line'"><u><xsl:copy-of select="$italic"/></u></xsl:when>
          <xsl:otherwise><xsl:copy-of select="$italic"/></xsl:otherwise>
        </xsl:choose>
      </xsl:template>
    </xsl:stylesheet>
    

    给定您的示例输入,输出为:

    <?xml version="1.0" encoding="utf-8"?><QuestionText xml:space="preserve">
    
      <p>plain 1 <b>bold</b> plain 2 <i>italic</i> plain3 <u>underline</u><b>Bold</b></p>
      <p>plain <i>Italic</i> plain </p>
      <p><i><b>BoldItalic</b></i></p>
      <p>plain <b> Bold </b><i><b> BoldItalic </b></i><u><i><b> BoldItalicUnderline </b></i></u><i><b> BoldItalic </b></i><b> Bold </b> plain </p>
      <p>plain <u><i><b>BoldItalicUnderline </b></i></u> plain </p>
      <p>plain <b>Bold </b><i><b> Bold and Italic </b></i><u><i><b> Bold and Italic and Underline </b></i></u><i><b> Bold and Italic </b></i><b> Bold </b> plain </p>
    
        </QuestionText>
    

    【讨论】:

    • 我无法控制设置优先级。
    • 对不起,这是我的错误。请忽略我之前的评论。你能帮我解决问题的风格组合方面吗?我对 XSLT 比较陌生。
    • @teenboy:您可以使用 XSLT 2.0,还是仅限于 1.0?因为如果你可以使用 2.0,那么有一些功能可以让它变得更容易。
    • 感谢 LarsH。非常感谢您的帮助。一个(希望是)最后一个问题,在明确指定之前,如何防止在

      ...

      之间换行。

    • @teenboy:在"Paragraph" 模板中,将select="*" 添加到应用模板中。这将防止它在 &lt;p&gt; 元素之间复制(空白)文本节点,否则默认情况下会这样做。我会相应地更新我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多