【发布时间】:2011-07-19 00:08:55
【问题描述】:
显示的 XML 是我正在使用的简化版本。我正在使用 PHP,以及 DOMDocument 和 DOMXPath。
我有许多彼此相邻的相似节点,但子节点略有不同。鉴于我可以定位其中一个节点,根据孩子的内容,我如何使用XPath同时抓取前面的节点,最初选择的节点,后面的节点和后面两个位置的节点。
这是示例 XML:
<w:p>
<w:r>
<w:rPr>...</w:rPr>
<w:t>Text</w:t>
</w:r>
<w:r>
<w:rPr>...</w:rPr>
<w:fldChar w:fldCharType="begin" />
</w:r>
<w:r>
<w:rPr>...</w:rPr>
<w:instrText> MERGEFIELD [PatName] \* MERGEFORMAT </w:instrText>
</w:r>
<w:r>
<w:rPr>...</w:rPr>
<w:fldChar w:fldCharType="separate" />
</w:r>
<w:r>
<w:rPr>...</w:rPr>
<w:t>[PatName]</w:t>
</w:r>
<w:r>
<w:rPr>...</w:rPr>
<w:fldChar w:fldCharType="end" />
</w:r>
</w:p>
要使用的起始节点是 w:instrText 节点,XPath 看起来像:
//w:r[contains(w:instrText,'MERGFIELD [PatFirstName]')].
然后我可以使用前面的兄弟轴来定位上一个项目。 XPath 看起来像:
//w:r[contains(w:instrText,'MERGFIELD [PatFirstName]')]/preceding-sibling::w:r[1].
然后我想抓取包含 w:instrText 的原始 w:r,以及包含 w:fldChar 的剩余两个 w:r 节点,将 w:t 节点排除在选择之外。但是我为此编写 XPath 的尝试被打破了:
//w:r[contains(w:instrText,'MERGEFIELD [PatFirstName]')]/preceding-sibling::w:r[1]/following-sibling::w:r[1 and 2]
抓取了太多的节点,可能是因为原来的包含条件不适用于Following-sibling条件)。
最终,将从该 sn-p 中提取以下条目。
<w:r>
<w:rPr>...</w:rPr>
<w:fldChar w:fldCharType="begin" />
</w:r>
<w:r>
<w:rPr>...</w:rPr>
<w:instrText> MERGEFIELD [PatName] \* MERGEFORMAT </w:instrText>
</w:r>
<w:r>
<w:rPr>...</w:rPr>
<w:fldChar w:fldCharType="separate" />
</w:r>
<w:r>
<w:rPr>...</w:rPr>
<w:fldChar w:fldCharType="end" />
</w:r>
使用相对节点进行搜索很重要,因为在 XML 中可能存在其他类似的节点组合。
你们中的一些人可能会将此 XML 识别为用于合并字段的 Word 2003 XML 格式,其中大部分内容已删除。我正在尝试隔离包含 w:t 的 w:r 节点,因此我可以对其进行更新,并删除用于将其标识为合并字段的周围节点。
【问题讨论】: