gpt4 book ai didi

xml - 使用 XSLT 1.0 将 XML 元素根据某些条件按顺序分组到桶中

转载 作者:数据小太阳 更新时间:2023-10-29 02:27:43 25 4
gpt4 key购买 nike

假设我有一些要转换为 HTML 的 XML。 XML 分为有序的部分:

<?xml version="1.0" encoding="utf-8"?>
<root>
<section attr="someCriteria">
<h1>Title 1</h1>
<p>paragraph 1-1</p>
<p>paragraph 1-2</p>
</section>
<section attr="someOtherCriteria">
<h3>Subtitle 2</h3>
<ul>
<li>list item 2-1</li>
<li>list item 2-2</li>
<li>list item 2-3</li>
<li>list item 2-4</li>
</ul>
</section>
<section attr="anotherSetOfCriteria">
<warning>
Warning: This product could kill you
</warning>
</section>
<section attr="evenMoreCriteria">
<disclaimer>
You were warned
</disclaimer>
</section>
<section attr="criteriaSupreme">
<p>Copyright 1999-2011</p>
</section>
</root>

我有几个这样的 XML 文档。我需要根据标准对这些部分进行分组和转换。将有两种不同的桶。

  • 所以第一部分将在桶(例如 <div
    class="FormatOne"></div>
    )
  • 如果第二部分符合标准有资格获得“FormatOne”桶吧也将进入这个桶
  • 如果第三部分需要不同的桶(例如 <div
    class="FormatTwo"></div>
    )然后是一个新的桶被创建和部分内容放在这个桶里
  • 如果第四部分的存储桶需要“FormatOne”(与之前的格式不同),那么一个新的再次创建桶和部分内容放在这个桶里
  • 等如果每个部分的格式相同,则每个部分都将进入与前一个部分相同的存储桶。如果没有,则会创建一个新的存储桶。

所以对于每个文档,根据分桶的逻辑,文档可能会这样结束:

<body>
<div class="FormatOne">
<h1>Title 1</h1>
<p>paragraph 1-1</p>
<p>paragraph 1-2</p>
<h3>Subtitle 2</h3>
<ul>
<li>list item 2-1</li>
<li>list item 2-2</li>
<li>list item 2-3</li>
<li>list item 2-4</li>
</ul>
</div>
<div class="FormatTwo">
<span class="warningText">
Warning: This product could kill you
</span>
</div>
<div class="FormatOne">
<span class="disclaimerText"> You were warned</span>
<p class="copyright">Copyright 1999-2011</p>
</div>
</body>

这个:

<body>
<div class="FormatOne">
<h1>Title 1</h1>
<p>paragraph 1-1</p>
<p>paragraph 1-2</p>
<h3>Subtitle 2</h3>
</div>
<div class="FormatTwo">
<ul>
<li>list item 2-1</li>
<li>list item 2-2</li>
<li>list item 2-3</li>
<li>list item 2-4</li>
</ul>
</div>
<div class="FormatOne">
<span class="warningText">
Warning: This product could kill you
</span>
<span class="disclaimerText"> You were warned</span>
<p class="copyright">Copyright 1999-2011</p>
</div>
</body>

甚至这样:

<body>
<div class="FormatOne">
<h1>Title 1</h1>
<p>paragraph 1-1</p>
<p>paragraph 1-2</p>
<h3>Subtitle 2</h3>
<ul>
<li>list item 2-1</li>
<li>list item 2-2</li>
<li>list item 2-3</li>
<li>list item 2-4</li>
</ul>
<span class="warningText">
Warning: This product could kill you
</span>
<span class="disclaimerText"> You were warned</span>
<p class="copyright">Copyright 1999-2011</p>
</div>
</body>

取决于部分的定义方式。

有没有办法使用 XSLT 来执行这种类型的分组魔法?

任何帮助都会很棒。谢谢!

最佳答案

我想出了一个解决方案,即按顺序点击每个部分。每个部分的处理分为两部分:“外壳”和“内容”部分。 “外壳”负责渲染<div class="FormatOne">...</div>。位,“内容”负责呈现当前部分和所有后续部分的实际内容,直到找到不匹配的部分

当找到不匹配的部分时,控制将恢复为该部分的“shell”模板。

这提供了一点有趣的灵 active :“外壳”模板在匹配的内容上可能非常激进,而“内容”部分可能更挑剔。具体来说,对于您的第一个示例输出,您需要 warning元素显示为 <span class="warningText">...</span> ,这是通过更匹配的模板完成的。

所有“内容”模板在呈现其当前部分的内容后,调用一个命名模板来查找“下一个”适当的内容部分。这有助于巩固确定什么是“匹配”部分的规则。

You can see a working example here .

这是我的代码,旨在复制您在第一个示例中要求的内容:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />

<xsl:template match="/">
<body>
<xsl:apply-templates select="/root/section[1]" mode="shell" />
</body>
</xsl:template>

<xsl:template match="section[
@attr = 'someCriteria' or
@attr = 'someOtherCriteria' or
@attr = 'evenMoreCriteria' or
@attr = 'criteriaSupreme']" mode="shell">

<div class="FormatOne">
<xsl:apply-templates select="." mode="contents" />
</div>

<xsl:apply-templates select="following-sibling::section[
@attr != 'someCritera' and
@attr != 'someOtherCriteria' and
@attr != 'evenMoreCriteria' and
@attr != 'criteriaSupreme'][1]" mode="shell" />

</xsl:template>

<xsl:template name="nextFormatOne">
<xsl:variable name="next" select="following-sibling::section[1]" />
<xsl:if test="$next[
@attr = 'someCriteria' or
@attr = 'someOtherCriteria' or
@attr = 'evenMoreCriteria' or
@attr = 'criteriaSupreme']">
<xsl:apply-templates select="$next" mode="contents" />
</xsl:if>
</xsl:template>

<xsl:template match="section[
@attr = 'someCriteria' or
@attr = 'someOtherCriteria']" mode="contents">

<xsl:copy-of select="*" />

<xsl:call-template name="nextFormatOne" />
</xsl:template>

<xsl:template match="section[@attr = 'evenMoreCriteria']" mode="contents">
<span class="disclaimerText">
<xsl:value-of select="disclaimer" />
</span>

<xsl:call-template name="nextFormatOne" />
</xsl:template>

<xsl:template match="section[@attr = 'criteriaSupreme']" mode="contents">
<p class="copyright">
<xsl:value-of select="p" />
</p>

<xsl:call-template name="nextFormatOne" />
</xsl:template>

<xsl:template match="section[@attr = 'anotherSetOfCriteria']" mode="shell">
<div class="FormatTwo">
<xsl:apply-templates select="." mode="contents" />
</div>
<xsl:apply-templates select="
following-sibling::section[@attr != 'anotherSetOfCriteria'][1]"
mode="shell" />
</xsl:template>

<xsl:template name="nextFormatTwo">
<xsl:variable name="next" select="following-sibling::section[1]" />
<xsl:if test="$next[@attr = 'anotherSetOfCriteria']">
<xsl:apply-templates select="$next" mode="contents" />
</xsl:if>
</xsl:template>

<xsl:template
match="section[@attr = 'anotherSetOfCriteria']"
mode="contents">

<span class="warningText">
<xsl:value-of select="warning" />
</span>

<xsl:call-template name="nextFormatTwo" />
</xsl:template>

</xsl:stylesheet>

关于xml - 使用 XSLT 1.0 将 XML 元素根据某些条件按顺序分组到桶中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6448139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com