I use the following command converting a docx to odt, one of the bookmarks get lost.
"libreoffice --headless --convert-to odt output.docx --outdir ./"
----- output.docx
------- following bookmarks was created by python-docx
<w:p w14:paraId="5D4F37CC" w14:textId="1FE5A142" w:rsidR="007E1B42" w:rsidRDefault="00356283" w:rsidP="00356283">
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>a</w:t>
</w:r>
<w:bookmarkStart w:id="0" w:name="xxbookmark4"/>
<w:bookmarkEnd w:id="0"/>
</w:p>
<w:p w14:paraId="34895FBC" w14:textId="518CEA5B" w:rsidR="007E1B42" w:rsidRDefault="00CF7EC0" w:rsidP="00CF7EC0">
<w:pPr>
<w:pStyle w:val="Heading2"/>
</w:pPr>
<w:r>
<w:t>b</w:t>
</w:r>
<w:bookmarkStart w:id="0" w:name="xxbookmark5"/>
<w:bookmarkEnd w:id="0"/>
</w:p>
...
<w:p>
<w:pPr>
<w:pStyle w:val="Heading1"/>
</w:pPr>
<w:r>
<w:t>Index1</w:t>
</w:r>
<w:bookmarkStart w:id="0" w:name="xxbookmark34"/>
<w:bookmarkEnd w:id="0"/>
</w:p>
<w:p>
<w:r>
<w:t>--a......................................................</w:t>
</w:r>
<w:hyperlink w:anchor="xxbookmark4" w:history="1">
<w:r>
<w:rPr>
<w:rStyle w:val="Hyperlink"/>
</w:rPr>
<w:t>AAA</w:t>
</w:r>
</w:hyperlink>
</w:p>
<w:p>
<w:r>
<w:t>----b................................................</w:t>
</w:r>
<w:hyperlink w:anchor="xxbookmark5" w:history="1">
<w:r>
<w:rPr>
<w:rStyle w:val="Hyperlink"/>
</w:rPr>
<w:t>AAA</w:t>
</w:r>
</w:hyperlink>
</w:p>
<w:p>
<w:r>
<w:t>--Index1.......................................</w:t>
</w:r>
<w:hyperlink w:anchor="xxbookmark34" w:history="1">
<w:r>
<w:rPr>
<w:rStyle w:val="Hyperlink"/>
</w:rPr>
<w:t>AAA</w:t>
</w:r>
</w:hyperlink>
</w:p>
<w:p/>
---- output.odt
<text:h text:style-name="Heading_20_1" text:outline-level="1">
a
<text:bookmark text:name="xxbookmark4"/>
</text:h>
<text:h text:style-name="Heading_20_2" text:outline-level="2">
b
<text:bookmark text:name="xxbookmark5"/>
</text:h>
...
<text:h text:style-name="P1" text:outline-level="1">Index1</text:h>
# issue here: xxbookmark34 is lost.
Index1 was created using python-docx, the other two headings are just edit manually in Word.
Anybody can help, or give some hint.
I compared the xml file in docx and can not find any different between the "Index1" and other two.
I have this xml file (it's called "LogReg.xml" and it contains some information about a logistic regression (I am interested in the name of the features and their coefficient - I'll explain in more detail below):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PMML xmlns="http://www.dmg.org/PMML-4_4" xmlns:data="http://jpmml.org/jpmml-model/InlineTable" version="4.4">
<Header>
<Application name="JPMML-SkLearn" version="1.6.35"/>
<Timestamp>2022-02-15T09:44:54Z</Timestamp>
</Header>
<MiningBuildTask>
<Extension name="repr">PMMLPipeline(steps=[('classifier', LogisticRegression())])</Extension>
</MiningBuildTask>
<DataDictionary>
<DataField name="Target" optype="categorical" dataType="integer">
<Value value="0"/>
<Value value="1"/>
</DataField>
<DataField name="const" optype="continuous" dataType="double"/>
<DataField name="grade" optype="continuous" dataType="double"/>
<DataField name="emp_length" optype="continuous" dataType="double"/>
<DataField name="dti" optype="continuous" dataType="double"/>
<DataField name="Orig_FicoScore" optype="continuous" dataType="double"/>
<DataField name="inq_last_6mths" optype="continuous" dataType="double"/>
<DataField name="acc_open_past_24mths" optype="continuous" dataType="double"/>
<DataField name="mort_acc" optype="continuous" dataType="double"/>
<DataField name="mths_since_recent_bc" optype="continuous" dataType="double"/>
<DataField name="num_rev_tl_bal_gt_0" optype="continuous" dataType="double"/>
<DataField name="percent_bc_gt_75" optype="continuous" dataType="double"/>
</DataDictionary>
<RegressionModel functionName="classification" algorithmName="sklearn.linear_model._logistic.LogisticRegression" normalizationMethod="logit">
<MiningSchema>
<MiningField name="Target" usageType="target"/>
<MiningField name="const"/>
<MiningField name="grade"/>
<MiningField name="emp_length"/>
<MiningField name="dti"/>
<MiningField name="Orig_FicoScore"/>
<MiningField name="inq_last_6mths"/>
<MiningField name="acc_open_past_24mths"/>
<MiningField name="mort_acc"/>
<MiningField name="mths_since_recent_bc"/>
<MiningField name="num_rev_tl_bal_gt_0"/>
<MiningField name="percent_bc_gt_75"/>
</MiningSchema>
<Output>
<OutputField name="probability(0)" optype="continuous" dataType="double" feature="probability" value="0"/>
<OutputField name="probability(1)" optype="continuous" dataType="double" feature="probability" value="1"/>
</Output>
<RegressionTable intercept="0.8064694059338298" targetCategory="1">
<NumericPredictor name="const" coefficient="0.8013433785974717"/>
<NumericPredictor name="grade" coefficient="0.9010481046582982"/>
<NumericPredictor name="emp_length" coefficient="0.9460686056314133"/>
<NumericPredictor name="dti" coefficient="0.5117062988491518"/>
<NumericPredictor name="Orig_FicoScore" coefficient="0.07944303372859234"/>
<NumericPredictor name="inq_last_6mths" coefficient="0.20516234445402765"/>
<NumericPredictor name="acc_open_past_24mths" coefficient="0.4852503249658917"/>
<NumericPredictor name="mort_acc" coefficient="0.6673203078463711"/>
<NumericPredictor name="mths_since_recent_bc" coefficient="0.1962158305958366"/>
<NumericPredictor name="num_rev_tl_bal_gt_0" coefficient="0.12964661294856686"/>
<NumericPredictor name="percent_bc_gt_75" coefficient="0.04534570018290847"/>
</RegressionTable>
<RegressionTable intercept="0.0" targetCategory="0"/>
</RegressionModel>
</PMML>
I have parsed it using this code:
from lxml import objectify
path = 'LogReg.xml'
parsed = objectify.parse(open(path))
root = parsed.getroot()
data = []
if True:
for elt in root.RegressionModel.RegressionTable:
el_data = {}
for child in elt.getchildren():
el_data[child.tag] = child.text
data.append(el_data)
perf = pd.DataFrame(data)
I am interested in parsing this bit:
<RegressionTable intercept="0.8064694059338298" targetCategory="1">
<NumericPredictor name="const" coefficient="0.8013433785974717"/>
<NumericPredictor name="grade" coefficient="0.9010481046582982"/>
<NumericPredictor name="emp_length" coefficient="0.9460686056314133"/>
<NumericPredictor name="dti" coefficient="0.5117062988491518"/>
<NumericPredictor name="Orig_FicoScore" coefficient="0.07944303372859234"/>
<NumericPredictor name="inq_last_6mths" coefficient="0.20516234445402765"/>
<NumericPredictor name="acc_open_past_24mths" coefficient="0.4852503249658917"/>
<NumericPredictor name="mort_acc" coefficient="0.6673203078463711"/>
<NumericPredictor name="mths_since_recent_bc" coefficient="0.1962158305958366"/>
<NumericPredictor name="num_rev_tl_bal_gt_0" coefficient="0.12964661294856686"/>
<NumericPredictor name="percent_bc_gt_75" coefficient="0.04534570018290847"/>
</RegressionTable>
so that I can build the following dictionary:
myDict = {
"const : 0.8013433785974717,
"grade" : 0.9010481046582982,
"emp_length" : 0.9460686056314133,
"dti" : 0.5117062988491518,
"Orig_FicoScore" : 0.07944303372859234,
"inq_last_6mths" : 0.20516234445402765,
"acc_open_past_24mths" : 0.4852503249658917,
"mort_acc" : 0.6673203078463711,
"mths_since_recent_bc" : 0.1962158305958366,
"num_rev_tl_bal_gt_0" : 0.12964661294856686,
"percent_bc_gt_75" : 0.04534570018290847
}
Basically, in the dictionary the Key is the name of the feature and the value is the coefficient of the logistic regression.
Please can anyone help me with the code?
I'm not sure you need pandas for this, but you do need to handle the namespaces in your xml.
Try something along these lines:
myDict = {}
#register the namespace
ns = {'xx': 'http://www.dmg.org/PMML-4_4'}
#you could collapse the next two into one line, but I believe it's clearer this way
rt = root.xpath('//xx:RegressionTable[.//xx:NumericPredictor]',namespaces=ns)[0]
nps = rt.xpath('./xx:NumericPredictor',namespaces=ns)
for np in nps:
myDict[np.attrib['name']]=np.attrib['coefficient']
myDict
The output should be your expected output.
Trying to post the item in ebay motors using ebay api call - AddItem. It throws me an error saying as below. Could you please show some light on this.
Note - I am able to add the item manually in ebay motors with compatability. I fetched the item details (which is added manually) using the api call - GetItem. Placed the same details in the AddItem api call. Though it got failed with below error.
<ShortMessage>Category is not valid.</ShortMessage>
<LongMessage>The category is not valid, select another category.</LongMessage>
<ErrorCode>107</ErrorCode>
<SeverityCode>Error</SeverityCode>
<ErrorClassification>RequestError</ErrorClassification>
Request message is
<?xml version="1.0" encoding="UTF-8"?>
<AddItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<RequesterCredentials>
<eBayAuthToken>********PG1QKFIlH****</eBayAuthToken>
</RequesterCredentials>
<Version>967</Version>
<ErrorLanguage>en_US</ErrorLanguage>
<WarningLevel>High</WarningLevel>
<Item>
<Title>Sample ebay motor brake fitment product</Title>
<Description>Hummer Truck Right Side Mirror</Description>
<StartPrice currencyID="USD">236.0</StartPrice>
<Country>US</Country>
<Currency>USD</Currency>
<ListingDuration>Days_7</ListingDuration>
<Location>Los Angeles, California</Location>
<DispatchTimeMax>2</DispatchTimeMax>
<ConditionID>1000</ConditionID>
<PaymentMethods>PayPal</PaymentMethods>
<PayPalEmailAddress>w*****1#gmail.com</PayPalEmailAddress>
<Quantity>1</Quantity>
<PrimaryCategory>
<CategoryID>33562</CategoryID>
</PrimaryCategory>
<PictureDetails>
<GalleryType>Gallery</GalleryType>
<GalleryURL>http://****/z/QJsAAOSwXSJXPHk~/$_1.JPG?set_id=880000500F</GalleryURL>
<PhotoDisplay>PicturePack</PhotoDisplay>
<PictureURL>http://*****/z/QJsAAOSwXSJXPHk~/$_1.JPG?set_id=880000500F</PictureURL>
</PictureDetails>
<ShippingDetails>
<ApplyShippingDiscount>false</ApplyShippingDiscount>
<GlobalShipping>true</GlobalShipping>
<CalculatedShippingRate>
<WeightMajor measurementSystem="English" unit="lbs">0</WeightMajor>
<WeightMinor measurementSystem="English" unit="oz">0</WeightMinor>
</CalculatedShippingRate>
<ShippingServiceOptions>
<ShippingService>ShippingMethodStandard</ShippingService>
<ShippingServiceCost currencyID="USD">0.0</ShippingServiceCost>
<ShippingServicePriority>1</ShippingServicePriority>
<ExpeditedService>false</ExpeditedService>
<ShippingTimeMin>1</ShippingTimeMin>
<ShippingTimeMax>6</ShippingTimeMax>
<FreeShipping>true</FreeShipping>
</ShippingServiceOptions>
<ShippingType>Flat</ShippingType>
<ThirdPartyCheckout>false</ThirdPartyCheckout>
<TaxTable>
<TaxJurisdiction>
<JurisdictionID>CA</JurisdictionID>
<SalesTaxPercent>10.0</SalesTaxPercent>
<ShippingIncludedInTax>false</ShippingIncludedInTax>
</TaxJurisdiction>
</TaxTable>
<ShippingDiscountProfileID>0</ShippingDiscountProfileID>
<InternationalShippingDiscountProfileID>0</InternationalShippingDiscountProfileID>
<ExcludeShipToLocation>Alaska/Hawaii</ExcludeShipToLocation>
<ExcludeShipToLocation>US Protectorates</ExcludeShipToLocation>
<ExcludeShipToLocation>APO/FPO</ExcludeShipToLocation>
<ExcludeShipToLocation>Africa</ExcludeShipToLocation>
<ExcludeShipToLocation>Asia</ExcludeShipToLocation>
<ExcludeShipToLocation>Central America and Caribbean</ExcludeShipToLocation>
<ExcludeShipToLocation>Europe</ExcludeShipToLocation>
<ExcludeShipToLocation>Middle East</ExcludeShipToLocation>
<ExcludeShipToLocation>Oceania</ExcludeShipToLocation>
<ExcludeShipToLocation>Southeast Asia</ExcludeShipToLocation>
<ExcludeShipToLocation>South America</ExcludeShipToLocation>
<ExcludeShipToLocation>BM</ExcludeShipToLocation>
<ExcludeShipToLocation>GL</ExcludeShipToLocation>
<ExcludeShipToLocation>MX</ExcludeShipToLocation>
<ExcludeShipToLocation>PM</ExcludeShipToLocation>
<ExcludeShipToLocation>PO Box</ExcludeShipToLocation>
<SellerExcludeShipToLocationsPreference>true</SellerExcludeShipToLocationsPreference>
</ShippingDetails>
<ReturnPolicy>
<RefundOption>MoneyBack</RefundOption>
<Refund>Money Back</Refund>
<ReturnsWithinOption>Days_14</ReturnsWithinOption>
<ReturnsWithin>14 Days</ReturnsWithin>
<ReturnsAcceptedOption>ReturnsAccepted</ReturnsAcceptedOption>
<ReturnsAccepted>Returns Accepted</ReturnsAccepted>
<ShippingCostPaidByOption>Buyer</ShippingCostPaidByOption>
<ShippingCostPaidBy>Buyer</ShippingCostPaidBy>
<RestockingFeeValue>No</RestockingFeeValue>
<RestockingFeeValueOption>NoRestockingFee</RestockingFeeValueOption>
</ReturnPolicy>
<ItemCompatibilityList>
<Compatibility>
<NameValueList/>
<NameValueList>
<Name>Year</Name>
<Value>2008</Value>
</NameValueList>
<NameValueList>
<Name>Make</Name>
<Value>Workhorse Custom Chassis</Value>
</NameValueList>
<NameValueList>
<Name>Model</Name>
<Value>R26</Value>
</NameValueList>
<NameValueList>
<Name>Trim</Name>
<Value>Base Motor Home - Stripped Chassis</Value>
</NameValueList>
<NameValueList>
<Name>Engine</Name>
<Value>8.1L 496Cu. In. V8 GAS OHV Naturally Aspirated</Value>
</NameValueList>
<CompatibilityNotes></CompatibilityNotes>
</Compatibility>
<Compatibility>
<NameValueList/>
<NameValueList>
<Name>Year</Name>
<Value>1998</Value>
</NameValueList>
<NameValueList>
<Name>Make</Name>
<Value>Advance Mixer</Value>
</NameValueList>
<NameValueList>
<Name>Model</Name>
<Value>M</Value>
</NameValueList>
<NameValueList>
<Name>Trim</Name>
<Value>Base Straight Truck - Half Cab</Value>
</NameValueList>
<NameValueList>
<Name>Engine</Name>
<Value>-- DIESEL</Value>
</NameValueList>
<CompatibilityNotes></CompatibilityNotes>
</Compatibility>
<Compatibility>
<NameValueList/>
<NameValueList>
<Name>Year</Name>
<Value>1988</Value>
</NameValueList>
<NameValueList>
<Name>Make</Name>
<Value>Yugo</Value>
</NameValueList>
<NameValueList>
<Name>Model</Name>
<Value>GVS</Value>
</NameValueList>
<NameValueList>
<Name>Trim</Name>
<Value>Base Hatchback 3-Door</Value>
</NameValueList>
<NameValueList>
<Name>Engine</Name>
<Value>1.1L 1116CC l4 GAS SOHC Naturally Aspirated</Value>
</NameValueList>
<CompatibilityNotes></CompatibilityNotes>
</Compatibility>
<Compatibility>
<NameValueList/>
<NameValueList>
<Name>Year</Name>
<Value>1963</Value>
</NameValueList>
<NameValueList>
<Name>Make</Name>
<Value>Wolseley</Value>
</NameValueList>
<NameValueList>
<Name>Model</Name>
<Value>1500</Value>
</NameValueList>
<NameValueList>
<Name>Trim</Name>
<Value>Base</Value>
</NameValueList>
<NameValueList>
<Name>Engine</Name>
<Value>1.5L 1489CC 91Cu. In. l4 GAS OHV Naturally Aspirated</Value>
</NameValueList>
<CompatibilityNotes></CompatibilityNotes>
</Compatibility>
<Compatibility>
<NameValueList/>
<NameValueList>
<Name>Year</Name>
<Value>1928</Value>
</NameValueList>
<NameValueList>
<Name>Make</Name>
<Value>Yellow Cab</Value>
</NameValueList>
<NameValueList>
<Name>Model</Name>
<Value>Model D-1</Value>
</NameValueList>
<NameValueList>
<Name>Trim</Name>
<Value>Base</Value>
</NameValueList>
<NameValueList>
<Name>Engine</Name>
<Value>--</Value>
</NameValueList>
<CompatibilityNotes></CompatibilityNotes>
</Compatibility>
</ItemCompatibilityList>
</Item>
</AddItemRequest>
Make sure that you using the 100 as the value of the HTTP header X-EBAY-API-SITEID. This ensures that your request is routed to the eBay motors site where the category is valid. Using 0 in the header routes the request to ebay.com where the category is not valid.
If found several questions about how to convert a table (or query) into XML, but none that showed how to start with one main table and join several one:many satellite tables, and from that generate XML that represents the hierarchical structure of the data. So I thought I'd share this solution now that I've figured it out. If someone else has another way of doing this, please post another answer.
Given this contrived data:
create table #recipe (id int, name varchar(10))
create table #ingredient (recipe_id int, name varchar(30), quantity varchar(20), sort int)
create table #instruction (recipe_id int, task varchar(32), sort int)
insert into #recipe values (1, 'pizza'), (2, 'omelet')
insert into #ingredient values (1, 'pizza dough', '1 package', 1),
(1, 'tomato sauce', '1 can', 2),
(1, 'favorite toppings', 'you choose', 3),
(2, 'eggs', 'three', 1),
(2, 'a bunch of other ingredients', 'you choose', 2)
insert into #instruction values (1, 'pre-bake pizza dough', 1),
(1, 'add tomato sauce', 2),
(1, 'add toppings', 3),
(1, 'bake a little longer', 4),
(2, 'break eggs into mixing bowl', 1),
(2, 'beat yolks and whites together', 2),
(2, 'pour into large sauce pan', 3),
(2, 'add other ingredients', 4),
(2, 'fold in half', 5),
(2, 'cook until done', 6)
.
Which looks like this in tabular form:
#recipe
id name
----------- ----------
1 pizza
2 omelet
.
#ingredient
recipe_id name quantity sort
----------- ------------------------------ -------------------- -----------
1 pizza dough 1 package 1
1 tomato sauce 1 can 2
1 favorite toppings you choose 3
2 eggs three 1
2 a bunch of other ingredients you choose 2
.
#instruction
recipe_id task sort
----------- -------------------------------- -----------
1 pre-bake pizza dough 1
1 add tomato sauce 2
1 add toppings 3
1 bake a little longer 4
2 break eggs into mixing bowl 1
2 beat yolks and whites together 2
2 pour into large sauce pan 3
2 add other ingredients 4
2 fold in half 5
2 cook until done 6
.
I want to create an XML document that has one record for each recipe, and within each recipe element, I want a group of ingredients and another group of instructions, like this:
<recipes>
<recipe id="2" name="omelet">
<ingredients>
<ingredient name="eggs" quantity="three" />
<ingredient name="a bunch of other ingredients" quantity="you choose" />
</ingredients>
<instructions>
<instruction task="break eggs into mixing bowl" />
<instruction task="beat yolks and whites together" />
<instruction task="pour into large sauce pan" />
<instruction task="add other ingredients" />
<instruction task="fold in half" />
<instruction task="cook until done" />
</instructions>
</recipe>
<recipe id="1" name="pizza">
<ingredients>
<ingredient name="pizza dough" quantity="1 package" />
<ingredient name="tomato sauce" quantity="1 can" />
<ingredient name="favorite toppings" quantity="you choose" />
</ingredients>
<instructions>
<instruction task="pre-bake pizza dough" />
<instruction task="add tomato sauce" />
<instruction task="add toppings" />
<instruction task="bake a little longer" />
</instructions>
</recipe>
</recipes>
This SQL creates the desired XML verbatim:
select recipe.*,
(
select ingredient.name, ingredient.quantity
from #ingredient ingredient
where recipe.id = ingredient.recipe_id
order by ingredient.sort
for xml auto, root('ingredients'), type
),
(
select instruction.task
from #instruction instruction
where recipe.id = instruction.recipe_id
order by instruction.sort
for xml auto, root('instructions'), type
)
from #recipe as recipe
order by recipe.name
for xml auto, root('recipes'), type
I aliased the temp table names because using for xml auto on temp tables creates poorly named XML elements. This is how it looks:
<recipes>
<recipe id="2" name="omelet">
<ingredients>
<ingredient name="eggs" quantity="three" />
<ingredient name="a bunch of other ingredients" quantity="you choose" />
</ingredients>
<instructions>
<instruction task="break eggs into mixing bowl" />
<instruction task="beat yolks and whites together" />
<instruction task="pour into large sauce pan" />
<instruction task="add other ingredients" />
<instruction task="fold in half" />
<instruction task="cook until done" />
</instructions>
</recipe>
<recipe id="1" name="pizza">
<ingredients>
<ingredient name="pizza dough" quantity="1 package" />
<ingredient name="tomato sauce" quantity="1 can" />
<ingredient name="favorite toppings" quantity="you choose" />
</ingredients>
<instructions>
<instruction task="pre-bake pizza dough" />
<instruction task="add tomato sauce" />
<instruction task="add toppings" />
<instruction task="bake a little longer" />
</instructions>
</recipe>
</recipes>
.
This SQL creates another version of the XML with all data as values instead of attributes, but in the same basic hierarchical structure:
select recipe.*,
(
select ingredient.name, ingredient.quantity
from #ingredient ingredient
where recipe.id = ingredient.recipe_id
order by ingredient.sort
for xml path('ingredient'), root('ingredients'), type
),
(
select instruction.task
from #instruction instruction
where recipe.id = instruction.recipe_id
order by instruction.sort
for xml path('instruction'), root('instructions'), type
)
from #recipe as recipe
order by recipe.name
for xml path('recipe'), root('recipes'), type
.
This is how it looks:
<recipes>
<recipe>
<id>2</id>
<name>omelet</name>
<ingredients>
<ingredient>
<name>eggs</name>
<quantity>three</quantity>
</ingredient>
<ingredient>
<name>a bunch of other ingredients</name>
<quantity>you choose</quantity>
</ingredient>
</ingredients>
<instructions>
<instruction>
<task>break eggs into mixing bowl</task>
</instruction>
<instruction>
<task>beat yolks and whites together</task>
</instruction>
<instruction>
<task>pour into large sauce pan</task>
</instruction>
<instruction>
<task>add other ingredients</task>
</instruction>
<instruction>
<task>fold in half</task>
</instruction>
<instruction>
<task>cook until done</task>
</instruction>
</instructions>
</recipe>
<recipe>
<id>1</id>
<name>pizza</name>
<ingredients>
<ingredient>
<name>pizza dough</name>
<quantity>1 package</quantity>
</ingredient>
<ingredient>
<name>tomato sauce</name>
<quantity>1 can</quantity>
</ingredient>
<ingredient>
<name>favorite toppings</name>
<quantity>you choose</quantity>
</ingredient>
</ingredients>
<instructions>
<instruction>
<task>pre-bake pizza dough</task>
</instruction>
<instruction>
<task>add tomato sauce</task>
</instruction>
<instruction>
<task>add toppings</task>
</instruction>
<instruction>
<task>bake a little longer</task>
</instruction>
</instructions>
</recipe>
</recipes>
Originally I tried placing the ingredients and instructions in the main query's from clause with an inner join to the recipe table. But the instructions were all nested within the ingredients, which were nested within the recipe. When I moved them up to the select part of the query it straightened out the XML.
I have the following xml
<ListOrderItemsResult>
<OrderItems>
<OrderItem>
<OrderItemId>01691605007219</OrderItemId>
<GiftWrapPrice>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</GiftWrapPrice>
<QuantityOrdered>1</QuantityOrdered>
<GiftWrapTax>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</GiftWrapTax>
<SellerSKU>WB0812005-2</SellerSKU>
<Title>Solid Oak Silk Lined Wooden Gift Box for Whisky, Wine and Champagne (2 Pack)</Title>
<ShippingTax>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ShippingTax>
<ShippingPrice>
<Amount>0.99</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ShippingPrice>
<ItemTax>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ItemTax>
<ItemPrice>
<Amount>43.99</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ItemPrice>
<PromotionDiscount>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</PromotionDiscount>
<ASIN>B00911O3IY</ASIN>
<ConditionId>New</ConditionId>
<QuantityShipped>1</QuantityShipped>
<ConditionSubtypeId>New</ConditionSubtypeId>
<ConditionNote>Free Postage and Packaging / Brand New / Original Packaging / Dispatched from UK Warehouse by Royal Mail or Parcelforce</ConditionNote>
<ShippingDiscount>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ShippingDiscount>
</OrderItem>
<OrderItem>
<OrderItemId>14086955545403</OrderItemId>
<GiftWrapPrice>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</GiftWrapPrice>
<QuantityOrdered>1</QuantityOrdered>
<GiftWrapTax>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</GiftWrapTax>
<SellerSKU>WB0812005-2</SellerSKU>
<Title>Solid Oak Silk Lined Wooden Gift Box for Whisky, Wine and Champagne (2 Pack)</Title>
<ShippingTax>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ShippingTax>
<ShippingPrice>
<Amount>1.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ShippingPrice>
<ItemTax>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ItemTax>
<ItemPrice>
<Amount>43.99</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ItemPrice>
<PromotionDiscount>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</PromotionDiscount>
<ASIN>B00911O3IY</ASIN>
<ConditionId>New</ConditionId>
<QuantityShipped>1</QuantityShipped>
<ConditionSubtypeId>New</ConditionSubtypeId>
<ConditionNote>Free Postage and Packaging / Brand New / Original Packaging / Dispatched from UK Warehouse by Royal Mail or Parcelforce</ConditionNote>
<ShippingDiscount>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ShippingDiscount>
</OrderItem>
<OrderItem>
<OrderItemId>15068544085995</OrderItemId>
<GiftWrapPrice>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</GiftWrapPrice>
<QuantityOrdered>1</QuantityOrdered>
<GiftWrapTax>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</GiftWrapTax>
<SellerSKU>WB0812005-2</SellerSKU>
<Title>Solid Oak Silk Lined Wooden Gift Box for Whisky, Wine and Champagne (2 Pack)</Title>
<ShippingTax>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ShippingTax>
<ShippingPrice>
<Amount>1.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ShippingPrice>
<ItemTax>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ItemTax>
<ItemPrice>
<Amount>43.99</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ItemPrice>
<PromotionDiscount>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</PromotionDiscount>
<ASIN>B00911O3IY</ASIN>
<ConditionId>New</ConditionId>
<QuantityShipped>1</QuantityShipped>
<ConditionSubtypeId>New</ConditionSubtypeId>
<ConditionNote>Free Postage and Packaging / Brand New / Original Packaging / Dispatched from UK Warehouse by Royal Mail or Parcelforce</ConditionNote>
<ShippingDiscount>
<Amount>0.00</Amount>
<CurrencyCode>GBP</CurrencyCode>
</ShippingDiscount>
</OrderItem>
</ListOrderItemsResult>
I want to select each and have come up with the following code which works but only retrieves the first item and the qty
SELECT doc.value('(OrderItems/OrderItem/OrderItemId)[1]','nvarchar(255)') AS 'OrderItemId' ,doc.value('(OrderItems/OrderItem/QuantityOrdered)[1]', 'int') AS 'QuantityOrdered'
FROM #xml.nodes('/ListOrderItemsResult') AS ref ( doc )
Can anyone provide a solution that will return all the items i.e. the 3 items in the XML. I an aware it has something to do with the [1] instance but cannot work out how to return all items.
SELECT doc.value('./OrderItemId[1]/text()[1]','nvarchar(255)') AS 'OrderItemId',
doc.value('./QuantityOrdered[1]/text()[1]', 'int') AS 'QuantityOrdered'
FROM #xml.nodes('/ListOrderItemsResult/OrderItems/*') AS ref ( doc )