注意:编辑使元素和属性值可见(之前它们是不可见的,因为我使用尖括号)并提供完整的示例XML源文件 .
我正在尝试创建XSL来执行复杂的XML到XML转换 .
我的XML有一些文本元素 <a:t>
,它们有各种路径,以 /p:sld
或 /p:notes
开头,但总是以 /p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t
结尾 .
这些 <a:t>
元素需要根据路径的开始方式以及(有时存在的)前一个兄弟 <a:pPr>
到 <a:r>
的属性值转换为不同的目标XML元素,而 <a:r>
又是 <a:t>
的父级 .
这是源XML的最小版本,例如:http://pastie.org/9559309
以下是各种 <a:t>
元素的xpath以及它们的目标XML . Edit: I added a new item at the start of the items whose paths start /p:notes
-
xpath
/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t
至<Body>
-
xpath
/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t
(<a:r>
标签前面紧跟<a:pPr lvl="1">
)到<Bulleted>
-
xpath
/p:sld/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t
(<a:r>
标签前面紧跟<a:pPr lvl="2">
)到<Bulleted2>
-
xpath
/p:notes/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t
至<Body>
-
xpath
/p:notes/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t
(<a:r>
标签前面有兄弟姐妹<a:pPr lvl="1">
)到<Body>
-
xpath
/p:notes/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t
(<a:r>
标签前面紧跟兄弟<a:pPr lvl="2">
)到<Bulleted>
-
xpath
/p:notes/p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t
(<a:r>
标签前面有兄弟姐妹<a:pPr lvl="3">
)到<Bulleted2>
注意当 <a:pPr>
存在时,路径起点与 <a:pPr>
的属性值的交互是如何确定输出哪个xml元素的 . 例如:
元素 <a:t>
与父 <a:r>
紧接在 <a:pPr "lvl=1">
之前应该生成 <Bulleted>
如果源xpath开始 /p:sld
但是如果源路径启动 /p:notes
__646876_标记与其他所有相同应该是 <Body>
在输出中 .
最后,我还需要将根xpath /p:notes
附近的几个元素转换为 <PageBreak>
,将xpath /p:sld
转换为 <PageBreak>
.
输出XML应如下所示 . 编辑:现在匹配源xml的内容 .
<Document>
<PageBreak></PageBreak>
<bodytext>Activity 1:</bodytext>
<bodytext>Services Platform</bodytext>
<bodytext>Objective :</bodytext>
<Bulleted>The objective of this activity is to identify which services each node supports</Bulleted>
<bodytext>Description :</bodytext>
<Bulleted>This will be an individual activity. Using the information we just covered and the drawing on the next page fill in the table with the information requested by your Instructor</Bulleted>
<bodytext>IG: Mandatory individual activity. Time: 5 – 10 min.</bodytext>
<PageBreak></PageBreak>
<bodytext>2</bodytext>
<bodytext>Activity 1: </bodytext>
<bodytext>Services Platform</bodytext>
<bodytext>To complete this activity, use the following material:</bodytext>
<Bulleted>The drawing and table on the next page, along with the information provided by your Instructor.</Bulleted>
</Document>
<PageBreak>
是一个空元素, <bodytext>
和 <Bullet>
元素包含源XML中相关 <a:t>
的文本,源XML中的所有其他元素都被剥离 .
更新:我已经编写了一些xsl,它似乎应该能够在输入xml中获取每个a:t元素的内容,并在输出上放置相应的输出元素名称 . 身体被改为bodytext,这样我就不会出现身体成为保留html词的问题 .
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
<xsl:template match="/">
<xsl:for-each select="//a:t/">
<xsl:choose>
<xsl:when test="(count(ancestor::p:sld) > 0) and (count(ancestor::a:r[preceding-sibling[1]@lvl='1']) > 0">
<bulleted><xsl:value-of select="."/></bulleted>
</xsl:when>
<xsl:when test="(count(ancestor::p:sld) > 0) and (count(ancestor::a:r[preceding-sibling[1]@lvl='2']) > 0">
<bulleted2><xsl:value-of select="."/></bulleted2>
</xsl:when>
<xsl:when test="(count(ancestor::p:notes) > 0) and (count(ancestor::a:r[preceding-sibling[1]@lvl='2']) > 0">
<bulleted><xsl:value-of select="."/></bulleted>
</xsl:when>
<xsl:when test="(count(ancestor::p:notes) > 0) and (count(ancestor::a:r[preceding-sibling[1]@lvl='3']) > 0">
<bulleted><xsl:value-of select="."/></bulleted>
</xsl:when>
<xsl:otherwise>
<bodytext><xsl:value-of select="."/></bodytext>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我从Transform获得的语法错误与 a:t
使用前缀我不确定如何修复这些错误这一事实有关 .
我也不确定如何告诉Transform XSL处理器在输出上放置分页符,其中每个p.sld或p.notes元素出现在输入上并让它们显示在适当的位置 . 好像我应该做一个外部的“for-each /document/p.sld或/document/p.notes”命令
-
输出
<pagebreak></pagebreak>
标记对 -
然后在上面的代码中启动另一个内部for-each
a:t
,但仅限于当前由外部选择的p.sld
或p.notes
元素的范围 -
然后关闭外部for-each命令,发送处理器以查找源xml中的下一个
p.sld
或p.notes
.
感谢您的任何帮助,您可以提供 .