FOP - prevent block collapsing - apache-fop

I would like to show a tickbox on the pdf and tried to do it as:
<fo:table-row height="10pt">
<fo:table-cell>
<fo:block line-height="10pt" text-align="center" border-style="solid" border="1pt" white-space-collapse="false">
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block/>
</fo:table-cell>
</fo:table-row>
but instead of getting a box, I get a line ie a box width 1pt height.
How can I force FOP, not to collapse the block? I'm using Apache-Fop 1.0
Update1:
This works:
<fo:block text-align="left">
<fo:table text-align="left" table-layout="fixed">
<fo:table-column column-width="10pt"/>
<fo:table-column column-width="10pt"/>
<fo:table-body>
<fo:table-row height="10pt">
<fo:table-cell height="10pt">
<fo:block line-height="10pt" font-family="$_Fontfamily"
font-size="8pt">$row.getValue().get(0)
</fo:block>
</fo:table-cell>
<fo:table-cell height="10pt" width="10pt">
<fo:block text-align="center" border-style="solid" border="1pt"/>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
I want border on the second cell.
If I put a table into the second block, then it works ok.

Try:
<fo:table-row>
<fo:table-cell height="10pt" width="10pt">
<fo:block text-align="center" border-style="solid" border="1pt"/>
</fo:table-cell>
<fo:table-cell height="10pt">
<fo:block/>
</fo:table-cell>
</fo:table-row>
This is a real world example it produces two cells with the given measurements
<fo:table border="1pt solid black" width="18.5cm" table-layout="fixed">
<fo:table-body>
<fo:table-row>
<fo:table-cell height="20.0cm" width="16.3cm" border-right="1pt solid black">
<fo:block/>
</fo:table-cell>
<fo:table-cell height="20.0cm">
<fo:block/>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>

Related

What kind of newline character is in my multiline string literal?

I'm trying to replace a new line with something, or remove it, but I can't even figure out what kind of new line character it is. I've tried \n and \r as a regular expression:
var testStr =
"""
.db $82, $14, $2c, $62, $26, $10, $28, $80, $04
.db $82, $14, $2c, $62, $26, $10, $28, $80, $04
.db $82, $08, $1e, $5e, $18, $60, $1a, $80, $04
.db $82, $08, $1e, $5e, $18, $60, $1a, $86, $04
.db $83, $1a, $18, $16, $84, $14, $1a, $18, $0e, $0c
.db $16, $83, $14, $20, $1e, $1c, $28, $26, $87
.db $24, $1a, $12, $10, $62, $0e, $80, $04, $04
.db $00
"""
testStr = testStr.replacingOccurrences(of: "^\\r*", with: "!", options: .regularExpression)
testStr = testStr.replacingOccurrences(of: "^\\n*", with: "!", options: .regularExpression)
print(testStr) // does not replace new lines
Looks like you've made the RegEx a little more complicated than it needs to be. As mentioned in the comments, you can remove the beginning anchor ^ and the *. The newline characters the multiline literals creates are caught by \n
Also, remember that your indentation matters with multiline string literals. You want the ending """ to be at the level at which the text is indented.
var testStr =
"""
.db $82, $14, $2c, $62, $26, $10, $28, $80, $04
.db $82, $14, $2c, $62, $26, $10, $28, $80, $04
.db $82, $08, $1e, $5e, $18, $60, $1a, $80, $04
.db $82, $08, $1e, $5e, $18, $60, $1a, $86, $04
.db $83, $1a, $18, $16, $84, $14, $1a, $18, $0e, $0c
.db $16, $83, $14, $20, $1e, $1c, $28, $26, $87
.db $24, $1a, $12, $10, $62, $0e, $80, $04, $04
.db $00
"""
testStr = testStr.replacingOccurrences(of: "\\n", with: "!", options: .regularExpression)
print(testStr)
Yields:
.db $82, $14, $2c, $62, $26, $10, $28, $80, $04!.db $82, $14, $2c, $62, $26, $10, $28, $80, $04!.db $82, $08, $1e, $5e, $18, $60, $1a, $80, $04!.db $82, $08, $1e, $5e, $18, $60, $1a, $86, $04!.db $83, $1a, $18, $16, $84, $14, $1a, $18, $0e, $0c!.db $16, $83, $14, $20, $1e, $1c, $28, $26, $87!.db $24, $1a, $12, $10, $62, $0e, $80, $04, $04!.db $00

How to split array list into multiple rows and columns in scala

I am reading this XML file using scala and I had to define custom schema's for each table attribute as they are different.
<CATALOG>
<TABLE at_name="Furniture">
<ROWDATA>
<ROW typeid="0" caseid="0" key="1" code="0"/>
<ROW typeid="1" caseid="0" key="1" code="0"/>
<ROW typeid="1" caseid="1" key="1" code="0"/>
</ROWDATA>
</TABLE>
<TABLE at_name="Cutlery">
<ROWDATA>
<ROW cutleryTypeid="0" color="Blue" code="0"/>
<ROW cutleryTypeid="0" color="Blue" code="0"/>
</ROWDATA>
</TABLE>
<TABLE at_name="Apparel">
<ROWDATA>
<ROW ApparelTypeid="1" color="Blue" barcode="0111"/>
<ROW ApparelTypeid="0" color="Blue" barcode"1122"/>
</ROWDATA>
</TABLE>
<CATALOG>
I now have the following array list created like this(for attribute furniture):
val gl = DF.select("ROWDATA").rdd.map(r => r(0)).collect()
for(element<-gl)
{
println(element)
}
When I print the elements I get this:
[WrappedArray([0,0,1,0], [1,0,1,0], [1,1,1,0])]
I want this transformed into two outputs.
Output 1:
id elements
1 [0,0,1,0]
2 [1,0,1,0]
3 [1,0,1,0]
Then I want convert it like this:
Output 2:
id col1 col2 col3 col4
1 0 0 1 0
2 1 0 1 0
3 1 0 1 0
Any help on this please?

SQL Server 2016 XML Shredding

Have been trying to figure this out for a while without success, read like 10 posts and some other examples and the MS help, not resonating, need to shred some xml data with the following format:
<ncf_report xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://cp.com/rules/client">
<admin>
<quoteback name="abcd">ABCD A</quoteback>
<product_group>Abcd ABcd Abcd</product_group>
<pnc_account>123456</pnc_account>
<pnc_account_name>ABC</pnc_account_name>
<product_reference>123456789</product_reference>
<report_type>ABCDE</report_type>
<status>ABCDE</status>
<ownership>ABCD</ownership>
<report_code>1234</report_code>
<report_description>Abcde/report_description>
<purpose>ABCDEFGH</purpose>
<date_request_ordered>05/05/2020</date_request_ordered>
<date_request_received>05/05/2020</date_request_received>
<date_request_completed>05/05/2020</date_request_completed>
<time_report_processed>1028</time_report_processed>
<multiple_scores_ordered>false</multiple_scores_ordered>
<vendor name="Abcd" address="Abcd" />
<report>
<sequence>0000000001</sequence>
<count>0000000001</count>
</report>
</admin>
<report>
<alerts_scoring>
<scoring>
<score status="Abcd">
<model_label>ABCD</model_label>
<score>123</score>
<rating_state>AB</rating_state>
<classification> ABCD </classification>
<reason_codes>
<code>12</code>
<description>ABCD</description>
</reason_codes>
<reason_codes>
<code>12</code>
<description>ABCD</description>
</reason_codes>
<reason_codes>
<code>12</code>
<description>ABCD ABCD ABCD</description>
</reason_codes>
<reason_codes>
<code>12</code>
<description>ABCD ABCD ABCD</description>
</reason_codes>
</score>
</scoring>
<general>ABCD ABCD ABCD ORIGINAL REPORT DATE: 12/12/2000</general>
<general>ABCD ABCD ABCD</general>
<general> ABCD ABCD ABCD</general>
<general narrativeCode="Abcd Abcd">ABCD ABCD ABCD</general>
<general narrativeCode=" Abcd Abcd">ABCD ABCD ABCD</general>
<general narrativeCode=" Abcd Abcd">ABCD ABCD ABCD</general>
</alerts_scoring>
<vendor_dataset>
<subjects>
<subject type="Abcd" relationship_to_data="Abcd">
<name type="Abcd">
<first>XXXX</first>
<middle>X</middle>
<last>XXXX</last>
</name>
<birth_date>01/01/1900</birth_date>
<ssn>999999999</ssn>
<address type="Abcd" ref="1" />
<address type="Abcd" ref="2" />
<address type="Abcd" ref="3" />
</subject>
</subjects>
<addresses>
<address id="1">
<street1>ABCD</street1>
<city>ABCD</city>
<state>AB</state>
<postalcode>12345</postalcode>
<zip4>1234</zip4>
<date_first_at_address>01/02/1900</date_first_at_address>
<date_last_at_address>01/02/1900</date_last_at_address>
</address>
<address id="2">
<house>123</house>
<street1>ABCDE</street1>
<city>ABCDE</city>
<state>AB</state>
<postalcode>12345</postalcode>
<zip4>1234</zip4>
<date_first_at_address>00/00/1900</date_first_at_address>
<date_last_at_address>00/00/1900</date_last_at_address>
</address>
<address id="3">
<street1>ABCDE</street1>
<city>ABCDE</city>
<state>AB</state>
<postalcode>12345</postalcode>
<zip4>1234</zip4>
<date_first_at_address>00/00/1900</date_first_at_address>
<date_last_at_address>00/00/1900</date_last_at_address>
</address>
</addresses>
</vendor_dataset>
<summary>
<date_oldest_trade>00/00/1900</date_oldest_trade>
<date_latest_trade>00/00/1900</date_latest_trade>
<date_latest_activity>00/00/1900</date_latest_activity>
<includes_bankruptcies flag="true" date="02/02/2009" />
<includes_other_records public_records="false" collection="true" consumer_statement="false" />
<credit_range high="123456" low="1234" number_trade_lines="12" />
**<account_status_counters>
<account type="current" description="Pays Account as Agreed" status="1">12</account>
<account type="current" description="Status Not Known" status=" ">7</account>
<account type="former" description="Pays/Paid 30-60 Days or Max 2 Payments Past Due" status="2">5</account>
<account type="former" description="Pays/Paid 60-90 Days or Max 3 Payments Past Due" status="3">4</account>
<account type="former" description="Bad Debt" status="9">6</account>
</account_status_counters>**
I currently going down the path of trying to use the xml procedure but I could not get to the finish line with openxml as well. Trying to extract data in highlighted at bottom of xml
EXEC sp_xml_preparedocument #hdoc OUTPUT, #CreditScoreXML
SELECT * FROM OPENXML(#hdoc, '/<ncf_report xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://cp.com/rules/client">/admin/summary/account_status_counters')
WITH
(
[Ref_Number] VARCHAR(10) 'product_reference',
[current_account_type] VARCHAR(10) './account/#type',
[current_account_type_description] VARCHAR(50) './account/#description',
[current_account_type_description] VARCHAR(1) './account/#status'
You can define the namespace for your XML using WITH XMLNAMESPACES statement, then you can extract the values you need with .value().
I don't understand exactly the information you are trying to extract, but this should put you on the right track (I only put the first row of your xml to save space, you should put the entire XML fragment in the #xml variable):
declare #xml xml set #xml='
<ncf_report xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://cp.com/rules/client">
...
'
;WITH XMLNAMESPACES ('http://cp.com/rules/client' as ns1)
select
#xml.value('(ns1:ncf_report/ns1:admin/ns1:product_reference)[1]', 'varchar(10)') as Ref_Number
,#xml.value('(ns1:ncf_report/ns1:report/ns1:summary/ns1:account_status_counters/ns1:account[#type="current" and #status ="1"]/#description)[1]', 'varchar(50)') as CurrentDescription
,#xml.value('(ns1:ncf_report/ns1:report/ns1:summary/ns1:account_status_counters/ns1:account[#type="current" and #status ="1"])[1]', 'int') as CurrentStatus
,#xml.value('(ns1:ncf_report/ns1:report/ns1:summary/ns1:account_status_counters/ns1:account[#type="current" and #status =" "]/#description)[1]', 'varchar(50)') as CurrentDescription_2
,#xml.value('(ns1:ncf_report/ns1:report/ns1:summary/ns1:account_status_counters/ns1:account[#type="current" and #status =" "])[1]', 'int') as CurrentStatus_2
This sample query would extract:

Distance calculated wrongly with the ST_Distance function in PostgreSQL database?

We are developing an application that involves calculating the shortest distance for a given point against the polygons stored within the PostgreSQL table.
We are using the ST_Distance function from PostgreSQL database.
When we compare the calculated distance with the Google Earth, there is vast difference between them.
Of course, neither Google nor PostgreSQL could be wrong (or are they?), so we are obviously missing something here.
Any ideas what is going wrong?
I have given below the sample query that we have tested with PostgreSQL along with the screenshots from Google Earth.
SELECT ST_Distance(Place1, Place2) As Place1ToPlace2
, ST_Distance(Place1, Spot1) As Place1ToSpot1
, ST_Distance(Place1, Spot2) As Place1ToSpot2
, ST_Distance(Place2, Spot1) As Place2ToSpot1
, ST_Distance(Place2, Spot2) As Place2ToSpot2
FROM (SELECT
ST_PolygonFromText('SRID=4326;POLYGON((-74.0050636293915 40.75265123968514,-74.00500355126653 40.75268991743845,-74.00498169169283 40.75267084386348,-74.00503571044075 40.75263867886528,-74.0050636293915 40.75265123968514))') as Spot1
,ST_PolygonFromText('SRID=4326;POLYGON((-74.00503571044075 40.75263867886528,-74.00498225451273 40.75267084385684,-74.00495878551709 40.75265859837483,-74.00501023946696 40.75262521978885,-74.00503571044075 40.75263867886528))') as Spot2
,ST_GeogFromText('SRID=4326;POINT(-74.00489 40.752894)') As Place1
,ST_GeogFromText('SRID=4326;POINT(-74.004774 40.752846)') As Place2
) As foo ;
It results in following values:
place1toplace2 |place1tospot1 |place1tospot2 |place2tospot1 |place2tospot2 |
---------------|--------------|--------------|--------------|--------------|
11.152362504 |24.608417285 |25.977083731 |26.004190091 |26.011579435 |
Following are the screenshots from Google Earth:
Place1ToPlace2
Place1ToSpot1
Place1ToSpot2
Place2ToSpot1
Place2ToSpot2
Thanks in advance!!
Following are the KMLs exported from Google Earth:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>Spot 1.kml</name>
<Style id="inline">
<LineStyle>
<color>ff0000ff</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<fill>0</fill>
</PolyStyle>
</Style>
<Style id="inline0">
<LineStyle>
<color>ff0000ff</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<fill>0</fill>
</PolyStyle>
</Style>
<StyleMap id="inline1">
<Pair>
<key>normal</key>
<styleUrl>#inline</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#inline0</styleUrl>
</Pair>
</StyleMap>
<Placemark>
<name>Spot 1</name>
<styleUrl>#inline1</styleUrl>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-74.0050636293915,40.75265123968514,0 -74.00500355126653,40.75268991743845,0 -74.00498169169283,40.75267084386348,0 -74.00503571044075,40.75263867886528,0 -74.0050636293915,40.75265123968514,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>Spot 2.kml</name>
<Style id="inline">
<LineStyle>
<color>ff0000ff</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<fill>0</fill>
</PolyStyle>
</Style>
<StyleMap id="inline0">
<Pair>
<key>normal</key>
<styleUrl>#inline1</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#inline</styleUrl>
</Pair>
</StyleMap>
<Style id="inline1">
<LineStyle>
<color>ff0000ff</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<fill>0</fill>
</PolyStyle>
</Style>
<Placemark>
<name>Spot 2</name>
<styleUrl>#inline0</styleUrl>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-74.00503571044075,40.75263867886528,0 -74.00498225451273,40.75267084385684,0 -74.00495878551709,40.75265859837483,0 -74.00501023946696,40.75262521978885,0 -74.00503571044075,40.75263867886528,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>
!EDIT 2!
I have tried one more thing. I have taken the point from Spot1 that visually looks nearest to the Place1 and marked it as Place3.
When we look it on the map, it looks like Place3 is nearer to Place1 than Place2, but when checking with the query, distance to Place3 gives higher value.
I have checked with following query:
SELECT ST_Distance(Place1, Place2) As Place1ToPlace2
,ST_Distance(Place1, Place3) As Place1ToPlace3
FROM (SELECT
ST_GeogFromText('SRID=4326;POINT(-74.00489 40.752894)') As Place1
,ST_GeogFromText('SRID=4326;POINT(-74.004774 40.752846)') As Place2
,ST_GeogFromText('SRID=4326;POINT(-74.00500355126653 40.75268991743845)') As Place3
) As foo;
And it gives following result:
place1toplace2 |place1toplace3 |
---------------|---------------|
11.152362504 |24.608417285 |
While on the Map:
Place1ToPlace3
Following is the KML for Place1,Place2 and Place3 (I have removed the style related tags from KML)
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>Distance Comparison.kml</name>
<Folder>
<name>Distance Comparison</name>
<open>1</open>
<Style>
<ListStyle>
<listItemType>check</listItemType>
<bgColor>00ffffff</bgColor>
<maxSnippetLines>2</maxSnippetLines>
</ListStyle>
</Style>
<Placemark>
<name>Place 1 - 40°45&apos;9.78"N 74° 0&apos;18.07"W (40.752894, -74.00489)</name>
<open>1</open>
<LookAt>
<longitude>-74.00500758183839</longitude>
<latitude>40.75269419172616</latitude>
<altitude>0</altitude>
<heading>-0.0008536233435993688</heading>
<tilt>29.8433509629012</tilt>
<range>47.16429940085073</range>
<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
</LookAt>
<styleUrl>#msn_1</styleUrl>
<Point>
<gx:drawOrder>1</gx:drawOrder>
<coordinates>-74.00501944444444,40.75271666666666,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Place 2 - 40°45&apos;9.54"N 74° 0&apos;17.70"W (40.752846, -74.004774)</name>
<open>1</open>
<LookAt>
<longitude>-74.00500758183839</longitude>
<latitude>40.75269419172616</latitude>
<altitude>0</altitude>
<heading>-0.0008536233435993688</heading>
<tilt>29.8433509629012</tilt>
<range>47.16429940085073</range>
<gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
</LookAt>
<styleUrl>#msn_2</styleUrl>
<Point>
<gx:drawOrder>1</gx:drawOrder>
<coordinates>-74.00491666666667,40.75265,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>Place 3 - 40°45&apos;9.68"N 74° 0&apos;18.01"W (40.75268991743845 -74.00500355126653)</name>
<open>1</open>
<styleUrl>#msn_3</styleUrl>
<Point>
<coordinates>-74.00500277777778,40.75268888888889,0</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
Your features in PostGIS don't appear to be where they are in Google... Here's what I got by visualising it.
Now there are two more issues. First, the difference between geometry and geography. Second, distance calculations.
st_distance on geographies returns values in metres. That's why the output of your first query is basically what you'd expect, given the location of the features (because your points were geographies, Postgres cast the polygons to geography for you). However, st_distance on geometries returns values in the units of the underlying projection, in this case degrees. That explains the output of your second query.
On to distance calculation. Trying to be concise here, but the biggest thing affecting your calculation is the underlying projection. From my understanding, the geography type is better for larger areas - you'd get more accurate results using geometries in a suitable projection for the area you're analysing. The "suitable projection" depends on what parts of the world you're looking at and what your purpose is.
Also, don't assume Google's figures are correct - I did a quick search but didn't find anything on how they calculate their distances. If they use a different method you'll get a different answer...
EDIT
Here is the query with the coordinates as they appear in your screenshots. Note the differences in the coordinate values! Also, note that the degrees-minutes-seconds displayed in your screenshots do not match with the decimal degree values in brackets!
SELECT ST_Distance(Place1, Place2) As Place1ToPlace2
, ST_Distance(Place1, Spot1) As Place1ToSpot1
, ST_Distance(Place1, Spot2) As Place1ToSpot2
, ST_Distance(Place2, Spot1) As Place2ToSpot1
, ST_Distance(Place2, Spot2) As Place2ToSpot2
FROM (SELECT
ST_PolygonFromText('SRID=4326;POLYGON((-74.0050636293915 40.75265123968514,-74.00500355126653 40.75268991743845,-74.00498169169283 40.75267084386348,-74.00503571044075 40.75263867886528,-74.0050636293915 40.75265123968514))') as Spot1
,ST_PolygonFromText('SRID=4326;POLYGON((-74.00503571044075 40.75263867886528,-74.00498225451273 40.75267084385684,-74.00495878551709 40.75265859837483,-74.00501023946696 40.75262521978885,-74.00503571044075 40.75263867886528))') as Spot2
,ST_GeogFromText('SRID=4326;POINT( -74.005019 40.752717)') As Place1
,ST_GeogFromText('SRID=4326;POINT(-74.004917 40.752650)') As Place2
) As foo ;
The values returned are 11.38223433, 3.27827391, 5.99175215, 5.93327383, 3.65564537. They are within cm of the results from Google.
I potentially major problem I see is that you are mixing geometries and geographies in your call to ST_Distance. From a glance at Postgres' API, the ST_Distance function takes either geometries or geographies, but not both.
Please try the following query. Here, I have replaced your calls to ST_GeogFromText, which returns a geography, with ST_GeometryFromText, which returns a geometry.
SELECT ST_Distance(Place1, Place2) AS Place1ToPlace2,
ST_Distance(Place1, Spot1) AS Place1ToSpot1
ST_Distance(Place1, Spot2) AS Place1ToSpot2
ST_Distance(Place2, Spot1) AS Place2ToSpot1
ST_Distance(Place2, Spot2) AS Place2ToSpot2
FROM
(
SELECT ST_PolygonFromText('SRID=4326;POLYGON((-74.0050636293915 40.75265123968514,-74.00500355126653 40.75268991743845,-74.00498169169283 40.75267084386348,-74.00503571044075 40.75263867886528,-74.0050636293915 40.75265123968514))') AS Spot1,
ST_PolygonFromText('SRID=4326;POLYGON((-74.00503571044075 40.75263867886528,-74.00498225451273 40.75267084385684,-74.00495878551709 40.75265859837483,-74.00501023946696 40.75262521978885,-74.00503571044075 40.75263867886528))') AS Spot2,
ST_GeometryFromText('SRID=4326;POINT(-74.00489 40.752894)') AS Place1
ST_GeometryFromText('SRID=4326;POINT(-74.004774 40.752846)') AS Place2
) AS foo;

XML::twig to filter XML parent nodes in PERL

I have a xml snippet
<head>
<a>
<b attr_1=1>
<b attr_1=2>
<c attr_2 =3 attr_3 =5/>
<c attr_2 =4 attr_3 =6 />
</b>
</a>
<a>
<b attr_1=1/>
<b attr_1=3>
<c attr_2 =3 attr_3 =5/>
<c attr_2 =10 attr_3 =10/ >
</b>
</a>
</head>
Now only those node are legitimate which have <b attr_1 =3>(at least one) and at least one respective child <c> having attr_2=10 and attr_3 =10 is there.
Thus the ouput file should have following trade
<a>
<b attr_1=1/>
<b attr_1=3>(this is the legitimate value)
<c attr_2 =3 attr_3 =5/>
<c attr_2 =10 attr_3 =10/ >(this is the legitimate combination)
</b>
</a>
My Code is
use strict;
use warnings;
use XML::Twig;
my $twig = new XML::Twig( twig_handlers => { a=> \&a} );
$twig->parsefile('1511.xml');
$twig->set_pretty_print('indented');
$twig->print_to_file('out.xml');
sub a {
my ( $twig, $a ) = #_ ;
$a->cut
unless grep { $_->att( 'attr_1' ) eq '3' } $a->children( 'b' )
}
By this I am able to go till level . Please help if anybody can in explaining how to traverse and grep till node C which is inside node B.
You had some errors in your XML-file. Also you seem to have deleted some parts of your description. You can also set some attribute restrictions to handlers and the *child methods.
sub a {
my ( $twig, $a ) = #_ ;
my $cut = 1;
foreach my $b ($a->children('b[#attr_1="3"]')){
$cut &&= not grep {$_->att('attr_2') eq '10'
and $_->att('attr_3') eq '10'} $b->children('c');
}
$a->cut if $cut;
}
This is the file I used for testing:
<head>
<a>
<b attr_1="1" />
<b attr_1="2">
<c attr_2 ="3" attr_3 ="5"/>
<c attr_2 ="4" attr_3 ="6" />
</b>
</a>
<a>
<b attr_1="1"/>
<b attr_1="3">
<c attr_2 ="3" attr_3 ="5"/>
<c attr_2 ="10" attr_3 ="10" />
</b>
</a>
<a>
<b attr_1="1"/>
<b attr_1="3">
<c attr_2 ="3" attr_3 ="5"/>
<c attr_2 ="10" attr_3 ="12" />
</b>
</a>
</head>
The output:
<head>
<a>
<b attr_1="1"/>
<b attr_1="3">
<c attr_2="3" attr_3="5"/>
<c attr_2="10" attr_3="10"/>
</b>
</a>
</head>
Edit: If you really want to have only grep statements you could use some nested greps like this, though I'd advice you to use the above, more readable solution.
$a->cut unless
grep {grep {$_->att('attr_2') eq '10' and $_->att('attr_3') eq '10'}
$_->children('c')} $a->children('b[#attr_1="3"]');