Reputation: 3719
Here's some code I am currently using. Where I need help are $bn_name_search
and $bn_id_search
$xpath_base='/ItemSearchResponse/Items/Item[';
for ($i = 1; $i<=10; $i++)
{
$curr_item_base=$xpath_base.$i.']';
$bn_name_search=$curr_item_base.'/BrowseNodes//BrowseNode/Name/text()';
$bn_id_search=$curr_item_base.'/BrowseNodes//BrowseNode/BrowseNodeId/text()';
$bn_names=$parsed->xpath($bn_name_search);
$bn_ids=$parsed->xpath($bn_id_search);
}
This gives me all the browsnode names and all the broswnode ids. What I'd like to do now is find only the browsenode names "BrowseNode/Name/
" that are not "All Products" and only browsnode ids "BrowseNode/BrowseNodeId/
" share a "BrowseNode/
" with a name that is not "All Products" I don't have to test for the existance of BrowseNode/Name
. It won't be blank if there is an ID. If I can put two negative expressions it would be even better. I would omit those whose names are "All Products" and those whose names are "Departments"
EDIT:
Here's a block of the XML: Where it says "<Name>Departments</Name>
", I'd like to exclude that name and it's ID. If I have a similare one that says "<Name>All Products</Name>
" I'd also like to exclude that name and it's ID. (by ID, I mean <BrowseNodeId>
)
<BrowseNodes>
<BrowseNode>
<BrowseNodeId>2346727011</BrowseNodeId>
<Name>Casual</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1045024</BrowseNodeId>
<Name>Dresses</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1040660</BrowseNodeId>
<Name>Women</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1036682</BrowseNodeId>
<Name>Departments</Name>
<IsCategoryRoot>1</IsCategoryRoot>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1036592</BrowseNodeId>
<Name>Clothing & Accessories</Name>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</BrowseNodes>
Upvotes: 4
Views: 1525
Reputation: 3209
Without seeing how your xml is structured, I came up with xpath for what I thought you were trying to do. I also wasn't too sure about the BrowseNodeId
that "share" a browsenode name, I assumed this meant to give the BrowseNodeId
s for all BrowseNode
s that had the name set to this.
I combined your xpath outside of the php to visualize it better:
/ItemSearchResponse/Items/Item[i]/BrowseNodes//BrowseNode/Name/text()
/ItemSearchResponse/Items/Item[i]/BrowseNodes//BrowseNode/
Combined solution:
/ItemSearchResponse/Items/Item[i]/BrowseNodes//BrowseNode/Name[text()!='All Products']/text()
/ItemSearchResponse/Items/Item[i]/BrowseNodes//BrowseNode[Name/text()!='All Departments']/BrowseNodeId/text()
Php solution:
$xpath_base='/ItemSearchResponse/Items/Item[';
for ($i = 1; $i<=10; $i++)
{
$curr_item_base=$xpath_base.$i.']';
$bn_name_search=$curr_item_base.'/BrowseNodes//BrowseNode/Name[text()!='All Products']';
$bn_id_search=$curr_item_base.'/BrowseNodes//BrowseNode[Name/text()!='All Departments']/BrowseNodeId/text()';
$bn_names=$parsed->xpath($bn_name_search);
$bn_ids=$parsed->xpath($bn_id_search);
}
Updated
To combine the xpath, you could use concatenate |
:
/ItemSearchResponse/Items/Item[i]/BrowseNodes//BrowseNode[Name/text()!=\'Departments\' and Name/text()!=\'All Products\']/BrowseNodeId/text() |
/ItemSearchResponse/Items/Item[i]/BrowseNodes//BrowseNode/Name[text()!=\'All Products\' and text()!=\'Departments\']
php: (Updated)
$bn_combined_search=$curr_item_base.'/BrowseNodes//BrowseNode[Name/text()!=\'Departments\' and Name/text()!=\'All Products\']/BrowseNodeId/text() |'.$curr_item_base.'/BrowseNodes//BrowseNode/Name[text()!=\'All Products\' and text()!=\'Departments\']';
If I made a wrong assumption, post some of your xml and elaborate on the solution you're looking for. Hope this helps!
Upvotes: 2
Reputation: 243459
Use:
//BrowseNode
[not(contains('|Departments|All Products|',
concat('|', Name, '|')
)
)
]/Name
This expression selects any Name
elements that is a child of a BrowseNode
element and whose string value isn't one of the strings "Departments"
or "All Products"
.
Use:
//BrowseNode
[not(contains('|Departments|All Products|',
concat('|', Name, '|')
)
)
]
/BrowseNodeId
This selects any BrowseNodeId
element that is a child of a BrowseNode
element and that has a Name
sibling whose string value isn't one of the strings "Departments"
or "All Products"
.
XSLT - based verification:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select=
"//BrowseNode
[not(contains('|Departments|All Products|',
concat('|', Name, '|')
)
)
]/Name
"/>
=================
<xsl:copy-of select=
"//BrowseNode
[not(contains('|Departments|All Products|',
concat('|', Name, '|')
)
)
]
/BrowseNodeId
"/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the provided XML document:
<BrowseNodes>
<BrowseNode>
<BrowseNodeId>2346727011</BrowseNodeId>
<Name>Casual</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1045024</BrowseNodeId>
<Name>Dresses</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1040660</BrowseNodeId>
<Name>Women</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1036682</BrowseNodeId>
<Name>Departments</Name>
<IsCategoryRoot>1</IsCategoryRoot>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1036592</BrowseNodeId>
<Name>Clothing & Accessories</Name>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</BrowseNodes>
the two XPath expressions are evaluated and their results (separated by the "========"
string are copied to the output.
We can thus verify from the result of the transformation that exactly the wanted Name
and BrowseNodeId
elements are selected:
<Name>Casual</Name>
<Name>Dresses</Name>
<Name>Women</Name>
<Name>Clothing & Accessories</Name>
=================
<BrowseNodeId>2346727011</BrowseNodeId>
<BrowseNodeId>1045024</BrowseNodeId>
<BrowseNodeId>1040660</BrowseNodeId>
<BrowseNodeId>1036592</BrowseNodeId>
Upvotes: 2
Reputation: 1544
There you go:
$nodes = $parsed->xpath("//BrowseNode[Name!='Departments' and Name!='All Products']");
foreach ($nodes as $node) {
echo "Id: {$node->BrowseNodeId}, name: {$node->Name}\n";
}
Upvotes: 2