【问题标题】:How to get data between headers?如何在标头之间获取数据?
【发布时间】:2020-03-05 05:13:11
【问题描述】:

我是 xslt 的新手。我希望将以下输入转换为如下所示的输出:

输入:

<ATTRIBUTE-VALUE>
    <THE-VALUE>
        <div xmlns="http://www.w3.org/1999/xhtml">
            <h1 dir="ltr" id="_1536217498885">Main Description</h1>
            Line1 The main description text goes here.
            <p>Line2 The main description text goes here.</p>
            &lt;p&gt;Line3 The main description text goes here.&lt;/p&gt;
            <p><img alt="Embedded Image" class="embeddedImageLink" id="_1536739954166" src="_9c3778a0-d596-4eef-85fa-052a5e1b2166.jpg"/></p>
            <h1 dir="ltr" id="_1536217498886">Key Consideration</h1>
            <p>Line1 The key consideration text goes here.</p>
            <p>Line2 The key consideration text goes here.</p>
            <h1 dir="ltr" id="_1536217498887">Skills</h1>
            <p>Line1 The Skills text goes here.</p>
            <p>Line2 The Skills text goes here.</p>
            <p>Line3 The Skills text goes here.</p>
            <h1 dir="ltr" id="_1536217498888">Synonyms</h1>
            &lt;p&gt;The Synonyms text goes here.&lt;/p&gt;
        </div>
    </THE-VALUE>
</ATTRIBUTE-VALUE>

输出应该是:

<MainDescription>
    <![CDATA[
        <p>Line1 The main description text goes here.</p>
        <p>Line2 The main description text goes here.</p>
        <p>Line3 The main description text goes here.</p>
        <p><img alt="Embedded Image" class="embeddedImageLink" id="_1536739954166" src="_9c3778a0-d596-4eef-85fa-052a5e1b2166.jpg"/></p>
    ]]>
</MainDescription>
<KeyConsiderations>
    <![CDATA[
        <p>Line1 The key consideration text goes here.</p>
        <p>Line2 The key consideration text goes here.</p>
    ]]>
</KeyConsiderations>
<Skills>
    <p>Line1 The Skills text goes here.</p>
    <p>Line2 The Skills text goes here.</p>
    <p>Line3 The Skills text goes here.</p>
</Skills>
<Synonyms>
    <p>The Synonyms text goes here.</p>
</Synonyms>

我想要&lt;h1&gt; 之间的数据,它可以包含应该在输出中生成的任何 html 标记。我尝试了代码:https://xsltfiddle.liberty-development.net/bdxtqy/2。但它仅在数据包含在 html 标记下时才提供数据。请提供有关如何实现所需输出的指示。

XSL 代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns:exsl="http://exslt.org/common"
    exclude-result-prefixes="xhtml exsl"
    version="1.0">

  <xsl:import href="http://lenzconsulting.com/xml-to-string/xml-to-string.xsl"/>

  <xsl:output method="xml" indent="yes"
    cdata-section-elements="MainDescription KeyConsideration"/>
  <xsl:strip-space elements="*"/>

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

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

  <xsl:key name="h1-group" match="xhtml:div/*[not(self::xhtml:h1)]" use="generate-id(preceding-sibling::xhtml:h1[1])"/>

  <xsl:template match="xhtml:div[xhtml:h1]">
      <xsl:apply-templates select="xhtml:h1"/>
  </xsl:template>

  <xsl:template match="xhtml:h1">
      <xsl:element name="{translate(., ' ', '')}">
          <xsl:variable name="rtf-with-xhtml-ns-stripped">
              <xsl:apply-templates select="key('h1-group', generate-id())"/>
          </xsl:variable>
          <xsl:apply-templates select="exsl:node-set($rtf-with-xhtml-ns-stripped)/node()" mode="xml-to-string"/>
      </xsl:element>
  </xsl:template>

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

</xsl:stylesheet>

我得到的输出是:

<ATTRIBUTE-VALUE>
  <THE-VALUE>
    <MainDescription><![CDATA[<p>Line2 The main description text goes here.</p><p><img alt="Embedded Image" class="embeddedImageLink" id="_1536739954166" src="_9c3778a0-d596-4eef-85fa-052a5e1b2166.jpg" xmlns="http://www.w3.org/1999/xhtml"/></p>]]></MainDescription>
    <KeyConsideration><![CDATA[<p>Line1 The key consideration text goes here.</p><p>Line2 The key consideration text goes here.</p>]]></KeyConsideration>
    <Skills>&lt;p&gt;Line1 The Skills text goes here.&lt;/p&gt;&lt;p&gt;Line2 The Skills text goes here.&lt;/p&gt;&lt;p&gt;Line3 The Skills text goes here.&lt;/p&gt;</Skills>
    <Synonyms />
  </THE-VALUE>
</ATTRIBUTE-VALUE>

【问题讨论】:

  • 您能否在问题中包含您拥有的代码和您获得的当前结果,然后解释结果与预期不符的原因?您链接到的示例中的示例输入是否与您在问题中显示的示例不同?
  • 我尝试了xsltfiddle.liberty-development.net/bdxtqy/2 中的代码并将其应用于本文中提到的输入。如果文本包含在 html 标记中,则此代码可以正常工作。但是如果文本不在 html 标签中,我什么也得不到。
  • 好吧,您链接到的代码将元素节点与* 匹配,如果您还有其他节点要被标题包裹,请参阅xsltfiddle.liberty-development.net/bdxtqy/41。但是您的输入/输出转换似乎有几个要求,不清楚何时需要 CDATA,也不清楚所需输出 &lt;p&gt;Line1 The main description text goes here.&lt;/p&gt; 中的 p 元素来自哪里,看来您有各种要求最好问分别在单独的问题中。 `

标签: xslt xslt-1.0


【解决方案1】:

如果您更改代码以匹配 node() 而不是 * 的元素,您将获得包含的文本节点:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns:exsl="http://exslt.org/common"
    exclude-result-prefixes="xhtml exsl"
    version="1.0">

  <xsl:import href="http://lenzconsulting.com/xml-to-string/xml-to-string.xsl"/>

  <xsl:output method="xml" indent="yes"
    cdata-section-elements="MainDescription KeyConsideration"/>
  <xsl:strip-space elements="*"/>

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

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

  <xsl:key name="h1-group" match="xhtml:div/node()[not(self::xhtml:h1)]" use="generate-id(preceding-sibling::xhtml:h1[1])"/>

  <xsl:template match="xhtml:div[xhtml:h1]">
      <xsl:apply-templates select="xhtml:h1"/>
  </xsl:template>

  <xsl:template match="xhtml:h1[. = 'Main Description' or . = 'Key Consideration']">
      <xsl:element name="{translate(., ' ', '')}">
          <xsl:variable name="rtf-with-xhtml-ns-stripped">
              <xsl:apply-templates select="key('h1-group', generate-id())"/>
          </xsl:variable>
          <xsl:apply-templates select="exsl:node-set($rtf-with-xhtml-ns-stripped)/node()" mode="xml-to-string"/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="xhtml:h1">
      <xsl:element name="{translate(., ' ', '')}">
          <xsl:variable name="rtf-with-xhtml-ns-stripped">
              <xsl:apply-templates select="key('h1-group', generate-id())"/>
          </xsl:variable>
          <xsl:apply-templates select="exsl:node-set($rtf-with-xhtml-ns-stripped)/node()"/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="text()">
      <xsl:value-of select="." disable-output-escaping="yes"/>
  </xsl:template>

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

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bdxtqy/41

目前尚不清楚何时/何地要将Line1 The main description text goes here. 之类的纯文本包装到p 元素中。

对于使用disable-output-escaping 的CDATA 部分,我认为您需要覆盖导入的xml-to-string 样式表的text() 节点的模板:

  <xsl:template match="text()" mode="xml-to-string">
      <xsl:value-of select="." disable-output-escaping="yes"/>
  </xsl:template>

https://xsltfiddle.liberty-development.net/bdxtqy/42

我没有测试这是否会破坏任何东西。

【讨论】:

  • 谢谢马丁。对于非 cdata 部分,该代码按预期工作。 cdata-section 也有相同的输出。例如。 <p>第 3 行主要的描述文字放在这里。</p>在 Cdata-section 应该转换成

    Line3 的主要描述文字到这里。

  • 谢谢马丁,这就是我想要的。
  • 还有一个查询,该解决方案适用于 xsltfiddle.liberty-development.net,但不适用于带有 xalan_2.7.1 的 eclipse java 转换器。如果我用 node() 替换 *,我不会在 等标签中得到任何内容。你有什么想法吗?
  • @VishalSharnagat,不知道,我不像在 Java 世界中那样使用 Xalan,Saxon 很容易为您提供 XSLT 2 或 3。如果您需要解决该特定问题的帮助,我认为您最好的办法是询问一个新的、单独的问题,其中包含最少的 XML、XSLT、Java 代码细节,以允许其他人轻松重现该问题。然后希望有人能告诉如何解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
  • 1970-01-01
相关资源
最近更新 更多