xml – 如何使用XSLT包装一组相邻元素?

前端之家收集整理的这篇文章主要介绍了xml – 如何使用XSLT包装一组相邻元素?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一些 XML< ListItem>元素,我想用< List>包装任何连续的运行元素.所以,源XML看起来像这样:
<Section>
  <Head>Heading</Head>
  <Para>Blah</Para>
  <ListItem>item 1</ListItem>
  <ListItem>item 2</ListItem>
  <ListItem>item 3</ListItem>
  <ListItem>item 4</ListItem>
  <Para>Something else</Para>
</Section>

我想把它转换成这样的东西:

<Section>
  <Head>Heading</Head>
  <Para>Blah</Para>
  <List>
    <ListItem>item 1</ListItem>
    <ListItem>item 2</ListItem>
    <ListItem>item 3</ListItem>
    <ListItem>item 4</ListItem>
  </List>
  <Para>Something else</Para>
</Section>

使用XSLT.我敢肯定这很明显但是我不能在晚上的这个时候解决这个问题.谢谢!

编辑:大多数人都可以安全地忽略这一点.

这个XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root>
  <Story>
    <Section id="preface">
      <ChapterTitle>Redacted</ChapterTitle>
      <HeadA>Redacted</HeadA>
      <Body>Redacted</Body>
      <BulletListItem>Item1</BulletListItem>
      <BulletListItem>Item2</BulletListItem>
      <BulletListItem>Item3</BulletListItem>
      <BulletListItem>Item4</BulletListItem>
      <HeadA>Redacted</HeadA>
      <Body>Redacted</Body>
      <HeadA>Redacted</HeadA>
      <Body>Redacted</Body>
      <Body>Redacted<Italic>REDACTED</Italic>Redacted</Body>
      <BulletListItem>Second list Item1</BulletListItem>
      <BulletListItem>Second list Item2</BulletListItem>
      <BulletListItem>Second list Item3</BulletListItem>
      <BulletListItem>Second list Item4</BulletListItem>
      <Body>Redacted</Body>
    </Section>
  </Story>
</Root>

有了这个XSL:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

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

 <xsl:template match="BulletListItem
         [not(preceding-sibling::*[1][self::BulletListItem])]">
  <BulletList>
    <xsl:call-template name="identity"/>
    <xsl:apply-templates mode="copy" select="key('kFollowing',generate-id())"/>
  </BulletList>
 </xsl:template>

 <xsl:template match="BulletListItem[preceding-sibling::*[1][self::BulletListItem]]"/>

 <xsl:template match="BulletListItem" mode="copy">
  <xsl:call-template name="identity"/>
 </xsl:template>
</xsl:stylesheet>

当使用Ruby REXML处理并且XML / XSLT生成此XML(输出prettyprint)时:

<Root>
  <Story>
    <Section id='preface'>
      <ChapterTitle>
        Redacted
      </ChapterTitle>
      <HeadA>
        Redacted
      </HeadA>
      <Body>
        Redacted
      </Body>
      <BulletList>
        <BulletListItem>
          Item1
        </BulletListItem>
        <BulletListItem>
          Item2
        </BulletListItem>
        <BulletListItem>
          Item3
        </BulletListItem>
        <BulletListItem>
          Item4
        </BulletListItem>
        <BulletListItem>
          Second list Item2
        </BulletListItem>
        <BulletListItem>
          Second list Item3
        </BulletListItem>
        <BulletListItem>
          Second list Item4
        </BulletListItem>
      </BulletList>
      <HeadA>
        Redacted
      </HeadA>
      <Body>
        Redacted
      </Body>
      <HeadA>
        Redacted
      </HeadA>
      <Body>
        Redacted
      </Body>
      <Body>
        Redacted
        <Italic>
          REDACTED
        </Italic>
        Redacted
      </Body>
      <BulletList>
        <BulletListItem>
          Second list Item1
        </BulletListItem>
      </BulletList>
      <Body>
        Redacted
      </Body>
    </Section>
  </Story>
</Root>

你会看到两个列表被卡在一起,两者之间的位丢失了.不确定这是Ruby库中还是XSLT中的错误.

这个样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()[1]"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="ListItem">
        <List>
            <xsl:call-template name="ListItem"/>
        </List>
        <xsl:apply-templates select="following-sibling::node()
                                      [not(self::ListItem)][1]"/>
    </xsl:template>
    <xsl:template match="ListItem[preceding-sibling::node()[1]
                                              /self::ListItem]"
                  name="ListItem">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()[1]"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]
                                                 /self::ListItem"/>
    </xsl:template>
</xsl:stylesheet>

输出

<Section>
    <Head>Heading</Head>
    <Para>Blah</Para>
    <List>
        <ListItem>item 1</ListItem>
        <ListItem>item 2</ListItem>
        <ListItem>item 3</ListItem>
        <ListItem>item 4</ListItem>
    </List>
    <Para>Something else</Para>
</Section>

编辑3:使用条带空间来实现它的本质.

原文链接:https://www.f2er.com/xml/292543.html

猜你在找的XML相关文章