xsl - 标签位置与父级中混合的文本

发布于 2024-10-31 11:46:48 字数 885 浏览 0 评论 0原文

在 XSL 1.0 中,我试图区分以下两种情况,这两种情况都发生在我需要处理的输入 XML 中,并且每种情况的处理方式不同。

场景 1

<tag1><tag2/> some text</tag1>

场景 2

<tag1>some text <tag2/></tag1>

我有一个在 级别匹配的模板,在此我希望场景 1 忽略 ,在场景 2 我想插入
代替

我在这里和谷歌上进行了搜索,但似乎无法弄清楚如何根据 中的位置进行区分。

我研究了 preceding-siblinggenerate-id 并尝试使用类似的东西:-

 not(
    generate-id(
       preceding-sibling::node()[1]
    )
  = generate-id(
       preceding-sibling::text()[1]
    )
 )

position()

不在这里似乎也没有帮助,因为两者似乎都在节点级别运行?

任何想法都会受到欢迎吗?

谢谢 罗杰

In XSL 1.0, I am trying to distinguish between the following 2 scenarios which both occur within the input XML I need to process and each to be handled differently.

Scenario 1

<tag1><tag2/> some text</tag1>

Scenario 2

<tag1>some text <tag2/></tag1>

I have a template which matches at the <tag2/> level, within this I want scenario 1 to ignore <tag2/>, in scenario 2 I want to insert a <br/> in place of <tag2/>.

I have searched on here and on google but can't seem to figure out how to distinguish based on the position of <tag2/> within <tag1>.

I have looked into preceding-sibling and generate-id and tried to use something like:-

 not(
    generate-id(
       preceding-sibling::node()[1]
    )
  = generate-id(
       preceding-sibling::text()[1]
    )
 )

and the

position()

of <tag2/> doesn't seem to help here either as both appear to be operating at the node level??

Any ideas would be welcomed?

Thanks
Roger

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

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

发布评论

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

评论(3

公布 2024-11-07 11:46:48

看看这些模式

node()[1]

这匹配第一个节点子节点。

node()[1][self::tag2]

这匹配第一个节点子节点,它也是一个 tag2 元素。

node()[not(self::text()[not(normalize-space())])][1][self::tag2]

这匹配第一个子节点,它不是纯空白文本节点,也是一个 tag2 元素(如果您像使用 XHTML 输入那样保留纯空白文本节点)。

我给你这种方法是因为第一个和第二个模式是可流式前一个轴不可流式传输)。

注意:第二个必须重写为node()[position() = 1 and self::tag2]

Look at these patterns:

node()[1]

This match first node child.

node()[1][self::tag2]

This match first node child which is also a tag2 element.

node()[not(self::text()[not(normalize-space())])][1][self::tag2]

This match first node child which is not a whitespace only text node and also a tag2 element (in case you preserve whitespace only text node as you should with XHTML input).

I give you this approach because the first and second patterns are streamable (preceding axis is not streamable).

Note: The second must be rewrite as node()[position() = 1 and self::tag2].

表情可笑 2024-11-07 11:46:48

以下样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="tag2[preceding-sibling::text()]">
        <br/>
    </xsl:template>
</xsl:stylesheet>

在此输入上:

<items>
    <tag1><tag2/>some text</tag1>
    <tag1>some text <tag2/></tag1>
</items>

生成:

some text
some text <br/>

更复杂的解决方案需要有关所需输出的附加信息。

The following stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="tag2[preceding-sibling::text()]">
        <br/>
    </xsl:template>
</xsl:stylesheet>

On this input:

<items>
    <tag1><tag2/>some text</tag1>
    <tag1>some text <tag2/></tag1>
</items>

Produces:

some text
some text <br/>

A more complex solution would require additional information about the desired output.

亽野灬性zι浪 2024-11-07 11:46:48

更简单、更基本的解决方案

<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=
  "node()[self::tag2 and position()=1]"/>
 <xsl:template match=
  "node()[self::tag2 and position()=2]">
  <br/>
 </xsl:template>
</xsl:stylesheet>

应用于此 XML 文档时

<tag1><tag2/> some text</tag1>

产生所需的正确结果:

<tag1> some text</tag1>

应用于此文档时

<tag1>some text <tag2/></tag1>

再次生成想要的正确答案

<tag1>some text <br/>
</tag1>

解释

  1. 身份规则(模板)按原样复制每个节点。

  2. 覆盖身份规则的第一个模板与名称为 tag2 且在节点列表中的位置为 1 的任何节点匹配。它没有主体,因此 tag2 > 元素被忽略。

  3. 覆盖身份规则的第二个模板与第一个模板类似,但匹配的 tag2 节点的位置必须为 2。在本例中,它被替换为
    .

A simpler and more fundamental 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=
  "node()[self::tag2 and position()=1]"/>
 <xsl:template match=
  "node()[self::tag2 and position()=2]">
  <br/>
 </xsl:template>
</xsl:stylesheet>

When applied on this XML document:

<tag1><tag2/> some text</tag1>

produces the wanted, correct result:

<tag1> some text</tag1>

When applied on this document:

<tag1>some text <tag2/></tag1>

again the wanted, correct answer is produced:

<tag1>some text <br/>
</tag1>

Explanation:

  1. The identity rule (template) copies every node as-is.

  2. The first template that is overriding the identity rule matches any node whose name is tag2 and whose position in the node-list is 1. It has no body so the tag2 element is ignored.

  3. The second template that overrides the identity rule is similar to the first, but the position of the matched tag2 node has to be 2. In this case it is replaced by <br/>.

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