• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 353
  • Last Modified:

XPath query string problem

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
Eddie Shipman
Asked:
Eddie Shipman
  • 4
  • 3
  • 2
1 Solution
 
dualsoulCommented:
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
 
rdcproCommented:
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
 
Eddie ShipmanAll-around developerAuthor Commented:
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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
dualsoulCommented:
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
 
Eddie ShipmanAll-around developerAuthor Commented:
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
 
rdcproCommented:
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
 
Eddie ShipmanAll-around developerAuthor Commented:
That worked. Now to be able to get the name attribute from the returned node...
0
 
rdcproCommented:
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
 
Eddie ShipmanAll-around developerAuthor Commented:
I am parsing them and loading them into a listbox in a Delphi program.
Got it, anyway.

Thanks.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now