Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

XPath query string problem

Posted on 2004-08-03
9
322 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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
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
 
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

MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Unattended XML settings 4 122
Parsing the XML data to SQL Server 4 67
Insert Powershell variable into XML 4 53
ebay devID, appID, certID, userToken 2 51
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, …
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

839 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