基于可选标记的XML分割



我正在寻找一个简单的分割xml文件只是基于标签;假设3个标签(可选)总是重复,需要分割,如下所示:

输入

<?xml version="1.0" encoding="UTF-8"?>
<Test>
    <tag1>A</tag1>
    <tag2>B</tag2>
    <tag3>C</tag3>
    <tag1>1</tag1>
    <tag2>2</tag2>
    <tag3>3</tag3>
    <tag1>apple</tag1>
    <tag2>orange</tag2>
    <tag3>mango</tag3>
</Test>
预期输出

<Root>
    <Test>
        <tag1>A</tag1>
        <tag2>B</tag2>
        <tag3>C</tag3>
    </Test>
    <Test>
        <tag1>1</tag1>
        <tag2>2</tag2>
        <tag3>3</tag3>
    </Test>
    <Test>
        <tag1>apple</tag1>
        <tag2>orange</tag2>
        <tag3>mango</tag3>
    </Test>
</Root>

这里的挑战是所有3个标签都是可选的,可以或不可以出现在一个块中。如果没有可选选项——我的问题已经在这里得到了回答——仅基于标签

进行分割

感谢您的帮助

谢谢

如果我正确理解了需求,您想要做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Test">
    <Root>
        <xsl:apply-templates/>
    </Root>
</xsl:template>
<xsl:template match="tag1">
    <Test>
        <xsl:copy-of select=". | following-sibling::*[1][self::tag2 or self::tag3]"/>
        <xsl:if test="following-sibling::*[1][self::tag2]">
            <xsl:copy-of select="following-sibling::*[2][self::tag3] "/>
        </xsl:if>
    </Test>
</xsl:template>
<xsl:template match="tag2[not(preceding-sibling::*[1][self::tag1])]">
    <Test>
        <xsl:copy-of select=". | following-sibling::*[1][self::tag3]"/>
    </Test>
</xsl:template>
<xsl:template match="tag3[not(preceding-sibling::*[1][self::tag2 or self::tag1])]">
    <Test>
        <xsl:copy-of select="."/>
    </Test>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>

这将为每一个创建一个新组:

    a tag1元素;
  • 一个tag2元素不紧跟着tag1元素;
  • tag3元素,不紧接tag2tag1元素。

tag3结尾,或者以序列结束前的最后一个元素结尾,以先到者为准。

适用于以下测试输入:

XML>
<Test>
    <tag2>B</tag2>
    <tag3>C</tag3>
    <tag1>1</tag1>
    <tag3>3</tag3>
    <tag1>apple</tag1>
    <tag2>orange</tag2>
    <tag1>A</tag1>
    <tag2>B</tag2>
    <tag1>1</tag1>
    <tag3>3</tag3>
    <tag3>mango</tag3>
    <tag1>A</tag1>
    <tag2>B</tag2>
    <tag3>C</tag3>
</Test>

结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<Root>
   <Test>
      <tag2>B</tag2>
      <tag3>C</tag3>
   </Test>
   <Test>
      <tag1>1</tag1>
      <tag3>3</tag3>
   </Test>
   <Test>
      <tag1>apple</tag1>
      <tag2>orange</tag2>
   </Test>
   <Test>
      <tag1>A</tag1>
      <tag2>B</tag2>
   </Test>
   <Test>
      <tag1>1</tag1>
      <tag3>3</tag3>
   </Test>
   <Test>
      <tag3>mango</tag3>
   </Test>
   <Test>
      <tag1>A</tag1>
      <tag2>B</tag2>
      <tag3>C</tag3>
   </Test>
</Root>

这里有一个替代解决方案,它可以处理任何大小的组,只要组中至少有一个元素始终存在。

在本例中,每组中最多有5个元素,元素tag3将出现在每组中:

XML>
<Test>
    <tag1>A</tag1>
    <tag2>B</tag2>
    <tag3>C</tag3>
    <tag4>D</tag4>
    <tag5>E</tag5>
    <tag2>2</tag2>
    <tag3>3</tag3>
    <tag5>5</tag5>
    <tag3>C</tag3>
    <tag3>3</tag3>
    <tag4>4</tag4>
    <tag5>5</tag5>
    <tag2>B</tag2>
    <tag3>C</tag3>
    <tag4>D</tag4>
    <tag1>1</tag1>
    <tag3>3</tag3>
    <tag5>5</tag5>
</Test>
XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="elems-before" match="tag1 | tag2" use="generate-id(following-sibling::tag3[1])" />
<xsl:key name="elems-after"  match="tag4 | tag5" use="generate-id(preceding-sibling::tag3[1])" />
<xsl:template match="/Test">
    <Root>
        <xsl:for-each select="tag3">
            <Test>
                <xsl:copy-of select="key('elems-before', generate-id())"/>
                <xsl:copy-of select="."/>
                <xsl:copy-of select="key('elems-after', generate-id())"/>
            </Test>
        </xsl:for-each>             
    </Root>
</xsl:template>
</xsl:stylesheet>
结果

<?xml version="1.0" encoding="UTF-8"?>
<Root>
   <Test>
      <tag1>A</tag1>
      <tag2>B</tag2>
      <tag3>C</tag3>
      <tag4>D</tag4>
      <tag5>E</tag5>
   </Test>
   <Test>
      <tag2>2</tag2>
      <tag3>3</tag3>
      <tag5>5</tag5>
   </Test>
   <Test>
      <tag3>C</tag3>
   </Test>
   <Test>
      <tag3>3</tag3>
      <tag4>4</tag4>
      <tag5>5</tag5>
   </Test>
   <Test>
      <tag2>B</tag2>
      <tag3>C</tag3>
      <tag4>D</tag4>
   </Test>
   <Test>
      <tag1>1</tag1>
      <tag3>3</tag3>
      <tag5>5</tag5>
   </Test>
</Root>

相关内容

  • 没有找到相关文章

最新更新