【问题标题】:Using XPath to extract multiple relative nodes使用 XPath 提取多个相关节点
【发布时间】: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 节点,因此我可以对其进行更新,并删除用于将其标识为合并字段的周围节点。

【问题讨论】:

    标签: php xpath


    【解决方案1】:

    我得出的结论是,我所要求的对于仅 XPath 来说过于雄心勃勃。 follow-sibling 和 previous-sibling axes 是 1 或所有交易(除非有人可以向我展示其他方式)。

    我最终使用 XPath 根据 MERGEFIELD 获取我有兴趣替换的 w:t 节点,然后我遍历 DOM,使用 PHP 中的 DOMDocument 删除其他节点。

    这是我最终使用的 XPATH,表示为对 PHP 中变量的赋值。

    $query = '//w:r[preceding-sibling::w:r[2][contains(w:instrText,\'MERGEFIELD  '.$mergeField.'\')]]/w:t';
    

    【讨论】:

      猜你喜欢
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-10
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      相关资源
      最近更新 更多