1

我有一个看起来像这样的 XML(任意 XML 输入)

<NodeLevel1>
    <NodeLevel2>
        <NodeLevel3>
            Sample text 1
        </NodeLevel3>
    </NodeLevel2>

    <NodeLevel2>
        .
        .
        .
        ... <NodeLevelN>
                Some deep thought
            </NodeLevelN>
    </NodeLevel2>

    <NodeLevel2>
        Sample text 2
    </NodeLevel2>
    Sample text 3
</NodeLevel1>


XSLT 转换后我想要的是 4 个新的 XML,只包含一个文本节点,如以下 4 个 XML:

1.

    <NodeLevel1>
        <NodeLevel2>
            <NodeLevel3>
                Sample text 1
            </NodeLevel3>
        </NodeLevel2>
    </NodeLevel1>

2.

    <NodeLevel1>    
        <NodeLevel2>
            .
            .
            .
            ... <NodeLevelN>
                    Some deep thought
                </NodeLevelN>
        </NodeLevel2>
    </NodeLevel1>

3.

    <NodeLevel1>
        <NodeLevel2>
            Sample text 2
        </NodeLevel2>
    </NodeLevel1>

4.

    <NodeLevel1>
        Sample text 3
    </NodeLevel1>

最好的方法是什么?我正在使用 C++(我可以使用 libxml2 和 libxslt)谢谢!

4

1 回答 1

2

我会将 XSLT 2.0 与libxslt 一起使用,xsl:result-document或者在您的情况下与 libxslt 一起使用,您也可以使用exsl:document扩展元素:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0"
  xmlns:exsl="http://exslt.org/common"
  extension-element-prefixes="exsl"
  exclude-result-prefixes="exsl">

<xsl:template match="/">
  <xsl:apply-templates select="NodeLevel1/node()[self::* or self::text()[normalize-space()]]" mode="new-doc"/>
</xsl:template>

<xsl:template match="NodeLevel1/node()" mode="new-doc">
  <exsl:document href="result{position()}.xml">
    <NodeLevel1>
      <xsl:copy-of select="."/>
    </NodeLevel1>
  </exsl:document>
</xsl:template>

</xsl:stylesheet>

再考虑一下这个问题,我改进了样式表以使用任何类型的根元素:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0"
  xmlns:exsl="http://exslt.org/common"
  extension-element-prefixes="exsl"
  exclude-result-prefixes="exsl">

<xsl:template match="/">
  <xsl:apply-templates select="*/node()[self::* or self::text()[normalize-space()]]" mode="new-doc"/>
</xsl:template>

<xsl:template match="/*/node()" mode="new-doc">
  <exsl:document href="result{position()}.xml">
    <xsl:element name="{name(..)}" namespace="{namespace-uri(..)}">
      <xsl:copy-of select="."/>
    </xsl:element>
  </exsl:document>
</xsl:template>

</xsl:stylesheet>

[编辑] 如果你想使用像 Saxon、AltovaXML 或 XmlPrime 这样的 XSLT 2.0 处理器,这里有一个 XSLT 2.0 样式表:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

<xsl:template match="/">
  <xsl:apply-templates select="*/(* | text()[normalize-space()])" mode="new-doc"/>
</xsl:template>

<xsl:template match="/*/node()" mode="new-doc">
  <xsl:result-document href="result{position()}.xml">
    <xsl:element name="{name(..)}" namespace="{namespace-uri(..)}">
      <xsl:copy-of select="."/>
    </xsl:element>
  </xsl:result-document>
</xsl:template>

</xsl:stylesheet>
于 2012-08-27T11:04:27.627 回答