这是我的XML文档。我想将这个XML文档转换为另一个XML文档(请参阅必需的输出XML部分)。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:v="urn:schemas-microsoft-com:vml">
<w:body>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>Text1-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading2" />
</w:pPr>
<w:r>
<w:t>Text2-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>Text3-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>Text4-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading3" />
</w:pPr>
<w:r>
<w:t>Text2.1-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading2" />
</w:pPr>
<w:r>
<w:t>Text5-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>Text6-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading3" />
</w:pPr>
<w:r>
<w:t>Text7-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>Text8-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1" />
</w:pPr>
<w:r>
<w:t>Text9-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>Text10-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading2" />
</w:pPr>
<w:r>
<w:t>Text11-</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
</w:pPr>
<w:r>
<w:t>Text12-</w:t>
</w:r>
</w:p>
<w:p>
<w:r>
<w:pict>
<v:shape>
<v:textbox>
<w:txbxcontent>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1" />
</w:pPr>
<w:r>
<w:t>
Drawing Description_1
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1" />
</w:pPr>
<w:r>
<w:t>
Drawing Description_2
</w:t>
</w:r>
</w:p>
</w:txbxcontent>
</v:textbox>
</v:shape>
</w:pict>
</w:r>
</w:p>
</w:body>
</w:document>
所需的输出XML是:
<?xml version="1.0" encoding="utf-8"?><Document xmlns:v="urn:schemas-microsoft-com:vml" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<Paragraph>Text1-</Paragraph>
<Heading2>
<Title>Text2-</Title>
<Paragraph>Text3-</Paragraph>
<Paragraph>Text4-</Paragraph>
<Heading3>
<Title>Text2.1-</Title>
</Heading3>
</Heading2>
<Heading2>
<Title>Text5-</Title>
<Paragraph>Text6-</Paragraph>
<Heading3>
<Title>Text7-</Title>
<Paragraph>Text8-</Paragraph>
</Heading3>
</Heading2>
<Heading1>
<Title>Text9-</Title>
<Paragraph>Text10-</Paragraph>
<Heading2>
<Title>Text11-</Title>
<Paragraph>Text12-</Paragraph>
<txtContentGroup>
<Paragraph>Drawing Description_1</Paragraph>
<Paragraph>Drawing Description_2</Paragraph>
</txtContentGroup>
</Heading2>
</Heading1>
</Document>
这是我的XSLT2.0实现:
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:mf="http://example.com/mf"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"
xmlns:user="http://http://stackoverflow.com/questions/11356668"
exclude-result-prefixes="xs w fn mf user">
<xsl:output indent="yes"/>
<xsl:function name="mf:group" as="element()*">
<xsl:param name="paragraphs" as="element()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$paragraphs" group-starting-with="p[pPr/pStyle/@w:val = concat('Heading', $level)]">
<xsl:choose>
<xsl:when test="self::p[pPr/pStyle/@w:val = concat('Heading', $level)]">
<xsl:element name="Heading{$level}">
<Title>
<xsl:apply-templates select="./r/t"/>
</Title>
<xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
</xsl:element>
</xsl:when>
<xsl:when test="current-group()[self::p[pPr/pStyle/@w:val = concat('Heading', $level + 1)]]">
<xsl:sequence select="mf:group(current-group(), $level + 1)">
</xsl:sequence>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()">
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="document">
<Document>
<xsl:sequence select="mf:group(body/p, 1)"/>
</Document>
</xsl:template>
<xsl:template match="p">
<xsl:choose>
<xsl:when test="(./r/t)">
<xsl:choose>
<xsl:when test="descendant::w:p[w:r/w:t] | descendant::w:p[//w:r/w:t[ancestor::w:pict]][2] ">
<txtContentGroup>
<Paragraph>
<xsl:apply-templates select="./r/t"/>
</Paragraph>
<xsl:apply-templates select="descendant::w:p">
</xsl:apply-templates>
</txtContentGroup>
</xsl:when>
<xsl:otherwise>
<Paragraph>
<xsl:apply-templates select="./r/t"/>
</Paragraph>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="descendant::w:p[not(ancestor::w:tbl)]">
<xsl:apply-templates select="descendant::w:p">
</xsl:apply-templates>
</xsl:when>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/r/t">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
但它会产生以下输出:
<?xml version="1.0" encoding="utf-8"?><Document xmlns:v="urn:schemas-microsoft-com:vml" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<Paragraph>Text1-</Paragraph>
<Heading2>
<Title>Text2-</Title>
<Paragraph>Text3-</Paragraph>
<Paragraph>Text4-</Paragraph>
<Heading3>
<Title>Text2.1-</Title>
</Heading3>
</Heading2>
<Heading2>
<Title>Text5-</Title>
<Paragraph>Text6-</Paragraph>
<Heading3>
<Title>Text7-</Title>
<Paragraph>Text8-</Paragraph>
</Heading3>
</Heading2>
<Heading1>
<Title>Text9-</Title>
<Paragraph>Text10-</Paragraph>
<Heading2>
<Title>Text11-</Title>
<Paragraph>Text12-</Paragraph>
<Paragraph>Drawing Description_1</Paragraph>
<Paragraph>Drawing Description_2</Paragraph>
</Heading2>
</Heading1>
</Document>
我的情况是:
每当<w:p>
元素中包含多个descendant::w:p[w:r/w:t]
,并且descendant::w:p[w:r/w:t]
具有<w:pict>
的祖先时,我就想创建<txtContentGroup>
元素并将所有descendant::w:p[w:r/w:t]
放在其中。
对于这种输入,您应该使用模板规则,而不是深度嵌套的xsl:choot指令。您的英文声明
每当<w:p>
元素中包含多个descendant::w:p[w:r/w:t]
,并且它有<w:pict>
的祖先时,我想创建<txtContentGroup>
元素并将所有descendant::w:p[w:r/w:t]
放在其中。
直接映射到模板规则:
<xsl:template match="w:pict//w:p[descendant::w:p[w:r/w:t][2]]">
<textContentGroup>
<xsl:apply-templates select="descendant::w:p[w:r/w:t]"/>
</textContentGroup>
</xsl:template>