Xpath to select all and exclude child and its children

ⅰ亾dé卋堺 提交于 2019-12-06 05:55:57

问题


I have the Data below and I am trying to select all the nodes except RejectedRecords and all of its children.

<?xml version="1.0" encoding="UTF-8"?>
<inmsg>
  <BPDATA>
    <DATE_TIME>10072014084945</DATE_TIME>
  </BPDATA>
  <Orders>
    <Rejected>
      <RejectedRecords>
        <RecordNumber>1</RecordNumber>
        <RecordError>State Code is invalid</RecordError>
      </RejectedRecords>
      <RejectedRecords>
        <RecordNumber>2</RecordNumber>
        <RecordError>State Code is invalid</RecordError>
      </RejectedRecords>
      <FileName>Foo1.txt</FileName>
      <MessageType>Rejected</MessageType>
      <RecordCount>2</RecordCount>
      <TotalAmount>1050.01</TotalAmount>
    </Rejected>
    <Unrestricted>
      <FileName>Foo2.txt</FileName>
      <MessageType>UnrestrictedState</MessageType>
      <RecordCount>2</RecordCount>
      <TotalAmount>100.10</TotalAmount>
    </Unrestricted>
  </Orders>
  <PrimaryDocument SCIObjectID="6442821469081a3a3node1"/>
</inmsg>

I have tried a number of statements such as

//*/node()[not(parent::RejectedRecords) and not(self::RejectedRecords) and not(self::RecordNumber) and not(self::RecordError)]
//*[not(parent::RejectedRecords) and not(self::RejectedRecords)]
//*[not(descendant-or-self::RejectedRecords)]

No matter what I have used I am still getting the RejectedRecords node and its children because it is coming in with the Rejected node. What am I doing wrong?


回答1:


This expression selects all nodes, but does not include in the result set any nodes that are RejectedRecords or that have RejectedRecords as an ancestor:

//*[not(descendant::RejectedRecords) and not(ancestor-or-self::RejectedRecords)]

Here is a link to the result in XPath Tester




回答2:


XPath can only select whole subtrees, not change them or create new XML output.

If you select the //Orders element, it will always include the <Rejected/> ones. All you can do is eg. select all orders not rejected, but at the same time you will lose the nodes around:

//Orders/*[not(self::Rejected)]

Depending on how you use XPath, you might use it to actually delete the <Rejected/> elements by selecting them using XPath and then deleting it with the XML framework of your primary programming language.

If you want to create new results from an XML language, you have to use XSLT templates or XQuery (which is very close at XPath). Which better fits your problem depends on your actual requirements and needs.



来源:https://stackoverflow.com/questions/24188773/xpath-to-select-all-and-exclude-child-and-its-children

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!