Solved

XPath query string problem

Posted on 2004-08-03
9
315 Views
Last Modified: 2006-11-17
I am parsing a Delphi DFM form file that has been converted to XML and
I want to retrieve all nodes that have a TabOrder or ObjectProperty.PropertyType.Name
element but not a HelpContext element, but only if they are not a TCSObject element.

This doesn't work:
//*[(@type="object") and (not (TCSObject)) and (not(HelpContext)) and ((TabOrder) or (ObjectProperty.PropertyType.Name))]


Using MSXML4 this doesn't work either, it returns an Unknown Method "-->local-name()<--" error
//*[(@type="object") and (not (local-name()="TCSObject")) and (not(HelpContext)) and ((TabOrder) or (ObjectProperty.PropertyType.Name))]


Here is a snippet of the XML. In this sample, I only want to return
these nodes:

  <TPanel name="FHeaderPanel" type="object">
  <TLabel name="FDepartmentLabel" type="object">
  <TLabel name="FAccountLabel" type="object">
  <TCSComboBox name="FDepartmentCombo" type="object">
  <TCSMaskEdit name="FAccountIDEdit" type="object">

<?xml version="1.0"?>
<TIssueEditForm name="IssueEditForm" type="object">
  <Left type="smallint">311</Left>
  <Top type="smallint">221</Top>
  <Width type="smallint">569</Width>
  <Height type="smallint">493</Height>
  <Caption type="string">Issue</Caption>
  <Color type="identifier">clBtnFace</Color>
  <Font.Charset type="identifier">DEFAULT_CHARSET</Font.Charset>
  <Font.Color type="identifier">clWindowText</Font.Color>
  <Font.Height type="shortint">-11</Font.Height>
  <Font.Name type="string">MS Sans Serif</Font.Name>
  <Font.Style type="set">[]</Font.Style>
  <Menu type="identifier">FMainMenu</Menu>
  <OldCreateOrder type="boolean">False</OldCreateOrder>
  <OnClose type="identifier">FormClose</OnClose>
  <OnCreate type="identifier">FormCreate</OnCreate>
  <OnShow type="identifier">FormShow</OnShow>
  <PixelsPerInch type="shortint">96</PixelsPerInch>
  <TextHeight type="shortint">13</TextHeight>
  <TPanel name="FHeaderPanel" type="object">
    <Left type="shortint">0</Left>
    <Top type="shortint">0</Top>
    <Width type="smallint">561</Width>
    <Height type="smallint">237</Height>
    <Align type="identifier">alTop</Align>
    <BevelOuter type="identifier">bvNone</BevelOuter>
    <TabOrder type="shortint">0</TabOrder>
    <TLabel name="FDepartmentLabel" type="object">
      <Left type="shortint">4</Left>
      <Top type="shortint">8</Top>
      <Width type="shortint">58</Width>
      <Height type="shortint">13</Height>
      <Caption type="string">Department:</Caption>
    </TLabel>
    <TLabel name="FAccountLabel" type="object">
      <Left type="shortint">4</Left>
      <Top type="shortint">113</Top>
      <Width type="shortint">43</Width>
      <Height type="shortint">13</Height>
      <Caption type="string">Account:</Caption>
    </TLabel>
    <TCSLabel name="FProductLabel" type="object">
      <Left type="shortint">4</Left>
      <Top type="shortint">29</Top>
      <Width type="shortint">40</Width>
      <Height type="shortint">13</Height>
      <HelpContext type="smallint">9236</HelpContext>
      <Caption type="string">Product:</Caption>
      <ObjectProperty.PropertyType.Name type="string">Unknown
</ObjectProperty.PropertyType.Name>
      <ObjectProperty.PropertyType.DataType.DataType type="shortint">0
</ObjectProperty.PropertyType.DataType.DataType>
      <ObjectProperty.PropertyType.DispatchID type="shortint">0
</ObjectProperty.PropertyType.DispatchID>
    </TCSLabel>
    <TCSComboBox name="FDepartmentCombo" type="object">
      <Left type="shortint">63</Left>
      <Top type="shortint">4</Top>
      <Width type="smallint">205</Width>
      <Height type="shortint">21</Height>
      <Content type="identifier">cbcDepartments</Content>
      <ObjectProperty.ObjectControl type="identifier">FDepartmentObject
</ObjectProperty.ObjectControl>
      <ObjectProperty.PropertyType.Name type="string">Surrogate
</ObjectProperty.PropertyType.Name>
      <ObjectProperty.PropertyType.DataType.DataType type="shortint">8
</ObjectProperty.PropertyType.DataType.DataType>
      <ObjectProperty.PropertyType.DispatchID type="shortint">1
</ObjectProperty.PropertyType.DispatchID>
      <ObjectProperty.PropertyType.AutoUpdate type="boolean">False
</ObjectProperty.PropertyType.AutoUpdate>
      <AllowBlank type="boolean">False</AllowBlank>
      <ReadOnly type="boolean">False</ReadOnly>
      <Activate type="boolean">True</Activate>
      <BorderColor type="identifier">clBtnShadow</BorderColor>
      <Flat type="boolean">True</Flat>
      <ShowBorder type="boolean">True</ShowBorder>
      <Style type="identifier">csDropDownList</Style>
      <ItemHeight type="shortint">13</ItemHeight>
      <TabOrder type="shortint">0</TabOrder>
      <OnChange type="identifier">DepartmentChange</OnChange>
      <ControlRights type="identifier">crInherited</ControlRights>
    </TCSComboBox>
    <TCSMaskEdit name="FProductIDEdit" type="object">
      <Left type="shortint">63</Left>
      <Top type="shortint">25</Top>
      <Width type="smallint">184</Width>
      <Height type="shortint">21</Height>
      <HelpContext type="smallint">9236</HelpContext>
      <ReadOnly type="boolean">False</ReadOnly>
      <TabOrder type="shortint">1</TabOrder>
      <OnChange type="identifier">IDChange</OnChange>
      <OnExit type="identifier">IDExit</OnExit>
      <ObjectProperty.ObjectControl type="identifier">FProductObject
</ObjectProperty.ObjectControl>
      <ObjectProperty.PropertyType.Name type="string">ID
</ObjectProperty.PropertyType.Name>
      <ObjectProperty.PropertyType.DataType.DataType type="shortint">8
</ObjectProperty.PropertyType.DataType.DataType>
      <ObjectProperty.PropertyType.DispatchID type="shortint">2
</ObjectProperty.PropertyType.DispatchID>
      <ObjectProperty.PropertyType.AutoUpdate type="boolean">False
</ObjectProperty.PropertyType.AutoUpdate>
      <Activate type="boolean">True</Activate>
      <BorderColor type="identifier">clBtnShadow</BorderColor>
      <Flat type="boolean">True</Flat>
      <ShowBorder type="boolean">True</ShowBorder>
      <ControlRights type="identifier">crInherited</ControlRights>
    </TCSMaskEdit>
    <TCSMaskEdit name="FAccountIDEdit" type="object">
      <Left type="shortint">63</Left>
      <Top type="shortint">109</Top>
      <Width type="smallint">184</Width>
      <Height type="shortint">21</Height>
      <ReadOnly type="boolean">False</ReadOnly>
      <TabOrder type="shortint">6</TabOrder>
      <OnChange type="identifier">IDChange</OnChange>
      <OnExit type="identifier">IDExit</OnExit>
      <ObjectProperty.ObjectControl type="identifier">FAccountObject
</ObjectProperty.ObjectControl>
      <ObjectProperty.PropertyType.Name type="string">ID
</ObjectProperty.PropertyType.Name>
      <ObjectProperty.PropertyType.DataType.DataType type="shortint">8
</ObjectProperty.PropertyType.DataType.DataType>
      <ObjectProperty.PropertyType.DispatchID type="shortint">2
</ObjectProperty.PropertyType.DispatchID>
      <ObjectProperty.PropertyType.AutoUpdate type="boolean">False
</ObjectProperty.PropertyType.AutoUpdate>
      <Activate type="boolean">True</Activate>
      <BorderColor type="identifier">clBtnShadow</BorderColor>
      <Flat type="boolean">True</Flat>
      <ShowBorder type="boolean">True</ShowBorder>
      <ControlRights type="identifier">crInherited</ControlRights>
    </TCSMaskEdit>
  </TPanel>
  <TPanel name="FMainPanel" type="object">
    <Left type="shortint">0</Left>
    <Top type="smallint">237</Top>
    <Width type="smallint">561</Width>
    <Height type="smallint">210</Height>
    <HelpContext type="longint">11182081</HelpContext>
    <Align type="identifier">alClient</Align>
    <BevelOuter type="identifier">bvNone</BevelOuter>
    <TabOrder type="shortint">1</TabOrder>
  </TPanel>
  <TCSObject name="FLocationObject" type="object">
    <ObjectType.Name type="string">ILocation</ObjectType.Name>
    <ObjectType.GUID.GUID type="string">{73923621-A2F1-11D1-A0ED-
0140339316E9}</ObjectType.GUID.GUID>
    <Binding type="identifier">bindLate</Binding>
    <ObjectProperty.PropertyType.Name type="string">Unknown
</ObjectProperty.PropertyType.Name>
    <ObjectProperty.PropertyType.DataType.DataType type="shortint">0
</ObjectProperty.PropertyType.DataType.DataType>
    <ObjectProperty.PropertyType.DispatchID type="shortint">0
</ObjectProperty.PropertyType.DispatchID>
    <ObjectProperty.PropertyType.AutoUpdate type="boolean">False
</ObjectProperty.PropertyType.AutoUpdate>
    <Persist type="boolean">True</Persist>
    <ProtectControls type="boolean">False</ProtectControls>
    <OnAssign type="identifier">LocationObjectAssign</OnAssign>
    <OnRelease type="identifier">LocationObjectRelease</OnRelease>
    <Left type="smallint">517</Left>
    <Top type="smallint">165</Top>
  </TCSObject>
  <TCSObject name="FProductObject" type="object">
    <ObjectType.Name type="string">IProduct</ObjectType.Name>
    <ObjectType.GUID.GUID type="string">{73923301-A2F1-11D1-A0ED-
0140339316E9}</ObjectType.GUID.GUID>
    <Binding type="identifier">bindLate</Binding>
    <ObjectProperty.PropertyType.Name type="string">Unknown
</ObjectProperty.PropertyType.Name>
    <ObjectProperty.PropertyType.DataType.DataType type="shortint">0
</ObjectProperty.PropertyType.DataType.DataType>
    <ObjectProperty.PropertyType.DispatchID type="shortint">0
</ObjectProperty.PropertyType.DispatchID>
    <ObjectProperty.PropertyType.AutoUpdate type="boolean">False
</ObjectProperty.PropertyType.AutoUpdate>
    <Persist type="boolean">True</Persist>
    <ProtectControls type="boolean">False</ProtectControls>
    <OnAssign type="identifier">ProductObjectAssign</OnAssign>
    <OnRelease type="identifier">ProductObjectRelease</OnRelease>
    <Left type="smallint">489</Left>
    <Top type="smallint">165</Top>
  </TCSObject>
</TIssueEditForm>
0
Comment
Question by:EddieShipman
  • 4
  • 3
  • 2
9 Comments
 
LVL 15

Expert Comment

by:dualsoul
ID: 11706371
hm...this one should be what you describe:


//*[not(self::TCSObject)][not(child::HelpContext)][@type='object'][child::TabOrder or child::ObjectProperty.PropertyType.Name]

, but it returns:

<TPanel name="FHeaderPanel" type="object"/>
<TCSComboBox name="FDepartmentCombo" type="object"/>
<TCSMaskEdit name="FAccountIDEdit" type="object"/>


, it seems right for me (as i able to check) . And the result you posted - is wrong, or may be xml sample, you posted, is not what do you mean. Please check carefully all stuff you posted and if above XPath is not what you want post again valid result with explanation for every node - why it should be returned.
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 11706986
I agree with Dualsoul.  I tried a couple things this morning, and this:

    <TLabel name="FDepartmentLabel" type="object">
      <Left type="shortint">4</Left>
      <Top type="shortint">8</Top>
      <Width type="shortint">58</Width>
      <Height type="shortint">13</Height>
      <Caption type="string">Department:</Caption>
    </TLabel>
    <TLabel name="FAccountLabel" type="object">
      <Left type="shortint">4</Left>
      <Top type="shortint">113</Top>
      <Width type="shortint">43</Width>
      <Height type="shortint">13</Height>
      <Caption type="string">Account:</Caption>
    </TLabel>

should not be in the results.  They have neither a TabOrder nor an ObjectProperty.PropertyType.Name child.

This was the XPath I used:

//*[not(self::TCSObject or child::HelpContext)][child::TabOrder | child::ObjectProperty.PropertyType.Name]

Regards,
Mike Sharp
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 11707469
Yes, I made a mistake. Some labels do have a HelpContext so I'm going to have to go with a Width property instead of TabOrder.
0
 
LVL 15

Expert Comment

by:dualsoul
ID: 11709351
you wanna XPath with Width instead of TabPropery?
try this:

//*[not(self::TCSObject or child::HelpContext)][child::Width | child::ObjectProperty.PropertyType.Name]

or you mean something else?
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 26

Author Comment

by:EddieShipman
ID: 11777409
Well, this isn't returning exactly the results I'm looking for.
It returns some nodes that have a Width but no HelpContext but
it also returns children of those nodes and some of those children
have a HelpContext.

The XML I posted above is not the complete, just a sample of one showing what
I wanted returned.

Is there any way to just return all nodes that have a Width and no HelpContext
regradless of parentage?
0
 
LVL 26

Accepted Solution

by:
rdcpro earned 500 total points
ID: 11778383
This part of the XPath filters to nodes that are not TCSObject nodes, and do not have HelpContext children.

//*[not(self::TCSObject or child::HelpContext)]

This part *further* filters those nodes to include only those with Width or ObjectProperty.PropertyType.Name children.  I don't see it returning any node with a HelpContext child.  Do you mean you don't want a HelpContext descendant?

//*[not(self::TCSObject or descendant::HelpContext)][child::Width | child::ObjectProperty.PropertyType.Name]

returns:

  <TLabel name="FDepartmentLabel" type="object">
  <TLabel name="FAccountLabel" type="object">
  <TCSComboBox name="FDepartmentCombo" type="object">
  <TCSMaskEdit name="FAccountIDEdit" type="object">

but does not include:
  <TPanel name="FHeaderPanel" type="object">

but TPanel contains children, at least one of which has a HelpContext child.

Regards,
Mike Sharp
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 11778706
That worked. Now to be able to get the name attribute from the returned node...
0
 
LVL 26

Expert Comment

by:rdcpro
ID: 11778867
Well, this would:

<xsl:value-of select="@name"/> assuming the context was one of the nodes in the XPath (ie: in a for-each or apply-templates).  If you simply want all the name attributes, and you want to iterate over them, you could do this:

<xsl:for-each select="//*[not(self::TCSObject or descendant::HelpContext)][child::Width | child::ObjectProperty.PropertyType.Name]">
<xsl:value-of select="@name"/>
</xsl:for-each>

Or even:

<xsl:for-each select="//*[not(self::TCSObject or descendant::HelpContext)][child::Width | child::ObjectProperty.PropertyType.Name]/@name">
<xsl:value-of select="."/>
</xsl:for-each>

Regards,
Mike Sharp
0
 
LVL 26

Author Comment

by:EddieShipman
ID: 11779212
I am parsing them and loading them into a listbox in a Delphi program.
Got it, anyway.

Thanks.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
The Confluence of Individual Knowledge and the Collective Intelligence At this writing (summer 2013) the term API (http://dictionary.reference.com/browse/API?s=t) has made its way into the popular lexicon of the English language.  A few years ago, …
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now