XSLT / Xpath:选择前面的注释

发布于 2024-08-09 17:45:30 字数 1193 浏览 8 评论 0原文

我有以下格式的 XML,我想重新格式化:

<blocks>
    <!-- === apples === -->
    <block name="block1">
        ...
    </block>
    <!-- === bananas === -->
    <block name="block2">
        ...
    </block>
    <!-- === oranges === -->
    <block name="block3">
        ...
    </block>
</blocks>

我的问题是我不知道如何选择每个块标签上方的注释。我有以下 XSL:

<xsl:template match="//blocks">
        <xsl:apply-templates select="block" />
</xsl:template>
<xsl:template match="block">
    <xsl:apply-templates select="../comment()[following-sibling::block[@name = ./@name]]" />
    <xsl:value-of select="./@name" />
</xsl:template>
<xsl:template match="comment()[following-sibling::block]">
    <xsl:value-of select="."></xsl:value-of>
</xsl:template>

我尝试的输出是:

=== 苹果 ===
区块1
===香蕉===
区块2
===橙子===
block3

但我能得到的最好的是:

=== 苹果 ===
===香蕉===
===橙子===
区块1
===苹果===
===香蕉===
===橙子===
区块2
===苹果===
===香蕉===
===橙子===
block3

我正在使用 PHP,如果这有什么区别的话。

I have XML in the following format which I want to reformat:

<blocks>
    <!-- === apples === -->
    <block name="block1">
        ...
    </block>
    <!-- === bananas === -->
    <block name="block2">
        ...
    </block>
    <!-- === oranges === -->
    <block name="block3">
        ...
    </block>
</blocks>

My problem is I can't figure out how to select the comments above each block tag. I have the following XSL:

<xsl:template match="//blocks">
        <xsl:apply-templates select="block" />
</xsl:template>
<xsl:template match="block">
    <xsl:apply-templates select="../comment()[following-sibling::block[@name = ./@name]]" />
    <xsl:value-of select="./@name" />
</xsl:template>
<xsl:template match="comment()[following-sibling::block]">
    <xsl:value-of select="."></xsl:value-of>
</xsl:template>

The output that I am trying for is:

=== apples ===
block1
=== bananas ===
block2
=== oranges ===
block3

But the best I can get is:

=== apples ===
=== bananas ===
=== oranges ===
block1
=== apples ===
=== bananas ===
=== oranges ===
block2
=== apples ===
=== bananas ===
=== oranges ===
block3

I am using PHP if that makes any difference.

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

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

发布评论

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

评论(2

往事随风而去 2024-08-16 17:45:30

您的样式表有点过于复杂。

您应该尝试下面的样式表,您会发现它与您想要的输出相匹配!

<xsl:template match="//blocks">
        <xsl:apply-templates select="block" />
</xsl:template>
<xsl:template match="block">
    <xsl:apply-templates select="preceding-sibling::comment()[1]" />
    <xsl:value-of select="./@name" />
</xsl:template>
<xsl:template match="comment()">
    <xsl:value-of select="."></xsl:value-of>
</xsl:template>

此代码始终匹配在当前块标记之前开始的 1 或 0 个注释。

Your stylesheet is a bit overly complicated.

You should try the stylesheet below and you will find that it matches the output that you want!

<xsl:template match="//blocks">
        <xsl:apply-templates select="block" />
</xsl:template>
<xsl:template match="block">
    <xsl:apply-templates select="preceding-sibling::comment()[1]" />
    <xsl:value-of select="./@name" />
</xsl:template>
<xsl:template match="comment()">
    <xsl:value-of select="."></xsl:value-of>
</xsl:template>

This code always matches 1 or 0 comments that start right before the current block tag.

后eg是否自 2024-08-16 17:45:30

您也可以在第一个 apply-templates 而不是第二个 apply-templates 中应用注释模板,以便按顺序发生 - 另外,此解决方案取决于源 xml 中数据的顺序..

<xsl:template match="//blocks">
        <xsl:apply-templates select="block | comment()" />
</xsl:template>

PS:- 您可以避免在表达式中使用“//”,因为它可能不是最佳的。

[编辑] 完整样式表

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="//blocks">
  <xsl:apply-templates select="block | comment()"/>
 </xsl:template>
 <xsl:template match="block">
  <xsl:value-of select="./@name"/>
 </xsl:template>
 <xsl:template match="comment()">
  <xsl:value-of select="."/>
 </xsl:template>
</xsl:stylesheet>

如果您需要换行符,请在打印块和注释中的值后添加以下语句。

<xsl:text>
</xsl:text>

You can apply the templates for comments also in your first apply-templates instead of the second one, so that it happens in order - Also, this solution is dependent on the order of the data in the source xml..

<xsl:template match="//blocks">
        <xsl:apply-templates select="block | comment()" />
</xsl:template>

PS:- You could avoid using "//" in your expressions as it can be non-optimal.

[EDIT] Complete Stylesheet

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:template match="//blocks">
  <xsl:apply-templates select="block | comment()"/>
 </xsl:template>
 <xsl:template match="block">
  <xsl:value-of select="./@name"/>
 </xsl:template>
 <xsl:template match="comment()">
  <xsl:value-of select="."/>
 </xsl:template>
</xsl:stylesheet>

Add the following statement if you want newlines, after you print the value in both the block and the comment.

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