显示的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]
抓取太多节点,可能是因为原始包含的条件不适用于以下兄弟条件。)
最终,将从该代码段中提取以下条目。
<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节点,因此我可以更新它,并删除用于将其标识为合并域的周围节点。
答案 0 :(得分:0)
我得出的结论是,我所要求的仅仅是XPath过于雄心勃勃。跟随兄弟和前兄弟轴是1或所有交易(除非有人可以告诉我)。
我最终使用XPath来获取我有兴趣替换的w:t节点,基于MERGEFIELD,然后我走DOM,使用PHP中的DOMDocument删除其他节点。
这是我最终使用的XPATH,表示为PHP中变量的赋值。
$query = '//w:r[preceding-sibling::w:r[2][contains(w:instrText,\'MERGEFIELD '.$mergeField.'\')]]/w:t';