I have a XML Document:
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>blahblah</title>
<subtitle>blahblah.</subtitle>
<link href="blahblah"/>
<link href="blahblah"/>
<updated>blahblah</updated>
<author>
<name>blahblah</name>
</author>
<id>blahblah</id>
<entry>
<title>blahblah</title>
<content type="html"><![CDATA[“some text.”]]></content>
</entry>
</feed>
I want to get the entry nodes content information, here's my code:
var xmlTreeVal = XDocument.Load("myxml.xml");
var returnVal = from item in xmlTreeVerse.Descendants("feed").Elements("entry")
select new VerseModel
{
Verse = item.Element("content").Value
};
The xml document is loading fine (as i could tell via debugging), but it keeps throwing a 'No sequential items found' error. How do I find the "content" nodes info?
Whenever your XML has a namespace (indicated by the xmlns attribute) you must reference the elements by also referencing their namespace. This is done by concatenating the namespace to the element name.
Also, you used xmlTreeVal but then reference xmlTreeVerse - it's probably not the problem but it's an inconsistency in the code you presented.
Try this:
var ns = xmlTreeVerse.Root.GetDefaultNamespace();
var returnVal = from item in xmlTreeVerse.Descendants(ns + "feed").Elements(ns + "entry")
select new
{
Verse = item.Element(ns + "content").Value
};
Related
In my flow in Mule 4 I am trying to query a database for specific data.
For example I want to run a query like this:
SELECT * FROM mulesoft WHERE plant = CCCNNB;
The thing is both plant and CCNNB need to be dynamic. They will come through an API request. I can handle the value to be dynamic, but I get empty results whenever I try to make the field dynamic.
I first create a variable which stores the json from the request:
set-variable value="#[payload]" doc:name="Set Variable" doc:id="8ed26865-d722-4fdb-9407-1f629b45d318" variableName="SORT_KEY"/>
Request looks like this:
{
"FILTER_KEY": "plant",
"FILTER_VALS": "CCNNB"
}
Afterwards in the db connector I configure the following:
<db:select doc:name="Select" doc:id="13a66f51-2a4e-4949-b383-86c43056f7a3" config-ref="Database_Config">
<db:sql><![CDATA[SELECT * FROM mulesoft WHERE :filter_key = :filter_val;]]></db:sql>
<db:input-parameters ><![CDATA[#[{
"filter_val": vars.SORT_KEY.FILTER_VALS,
"filter_key": vars.SORT_KEY.FILTER_KEY
}]]]></db:input-parameters>
Replacing :filter_key with plant works but as soon as I try to make it dynamic I get nothing in the response. It does not fail though, response code is 200 but I get nothing inside it.
How can I make this work?
You can directly use the stored variables in the query itself.
Query Should be an expression in DataWeave.
#["SELECT * FROM $(vars.table) WHERE $(vars.SORT_KEY.FILTER_KEY) = :filter_val"]
<db:select config-ref="Database_Config">
<db:sql><![CDATA[#["SELECT * FROM $(vars.table) WHERE $(vars.SORT_KEY.FILTER_KEY) = :filter_val"]]]></db:sql>
<db:input-parameters ><![CDATA[#[{
"filter_val": vars.SORT_KEY.FILTER_VALS
}]]]>
</db:input-parameters>
</db:select>
There is another way also to read values from payload to build a dynamic query as below
#["SELECT * FROM mulesoft
WHERE " ++ vars.SORT_KEY.FILTER_KEY ++ " = '" ++ vars.SORT_KEY.FILTER_VALS ++ "'"]
Below is the XML that is created for this, as a POC
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:os="http://www.mulesoft.org/schema/mule/os"
xmlns:salesforce="http://www.mulesoft.org/schema/mule/salesforce"
xmlns:db="http://www.mulesoft.org/schema/mule/db"
xmlns:xml-module="http://www.mulesoft.org/schema/mule/xml-module"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
http://www.mulesoft.org/schema/mule/os http://www.mulesoft.org/schema/mule/os/current/mule-os.xsd">
<http:listener-config name="HTTP_Listener_config1"
doc:name="HTTP Listener config"
doc:id="6d5de64b-1355-4967-9352-4b324f02c7ad">
<http:listener-connection host="0.0.0.0"
port="8081" />
</http:listener-config>
<db:config name="Database_Config" doc:name="Database Config"
doc:id="d5c4d49c-aef3-4d4a-a7b5-470da3354127">
<db:my-sql-connection host="localhost"
port="3306" user="root" password="admin123" database="Mysql" />
</db:config>
<flow name="testFlow"
doc:id="8cfea1b0-d244-40d9-989c-e136af0d9f80" initialState="started">
<http:listener doc:name="Listener"
doc:id="265e671b-7d2f-4f3a-908c-8065a5f36a07"
config-ref="HTTP_Listener_config1" path="test" />
<set-variable value="#[payload]" doc:name="Set Variable"
doc:id="265a16c5-68d4-4217-8626-c4ab0a3e38e5" variableName="SORT_KEY" />
<db:select doc:name="Select"
doc:id="bdf4a59c-0bcc-46ac-8258-f1f1762c4e7f"
config-ref="Database_Config">
<db:sql><![CDATA[#["SELECT * FROM mulesoft.mulesoft WHERE " ++ vars.SORT_KEY.FILTER_KEY ++ " = '" ++ vars.SORT_KEY.FILTER_VALS ++ "'"]]]></db:sql>
</db:select>
<ee:transform doc:name="Transform Message"
doc:id="72cbe69f-c52e-4df9-ba5b-dd751990bc08">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
</mule>
Explanation of the Flow
I am using the payload that is in Question
Seting a variable name "SORT_KEY", value of this varibale is complete payload that we receive.
then creating a dynamic query inside the Db connector
using transform message sending the data as response, that we received from DataBase
So, there are several issues here. One, the creation of the sql statement.
You can do DW inside the DB:SELECT component if you want, as shown by previous answers. Either the
#["SELECT * FROM myTable" ++ vars.myWhere]
OR
#["SELECT * FROM myTable $(vars.myWhere)"]
work.
The problem you will run into is that DataSense doesn't like this. Without the literal text for the column names, DataSense can't figure out what columns to retrieve so it raises an error "Unable to resolve value for the prameter: sql". This leaves an error in your code, which always gives me angst. I wish Mulesoft would resolve this problem.
BTW, if you do dynamic SQL, you should STILL use input parameters for each value to avoid SQL injections.
I have an "Idea" posted here to fix the bogus error: https://help.mulesoft.com/s/ideas#0872T000000XbjkQAC
Ok.
I'm writing a POC (Proof of Concept) Logic App.
The logic app has a Service Bus connector wired to a queue.
I'm using peek/complete/abandon.
I wrote a client app (dotnet c# console app) that writes messages to the queue (nothing really to do with the logic app part).
I'm setting the Content Type to "text/plain".
string payLoad = #"{ ""myid"": ""1000"", ""mymessage"": ""1000 is great"" , ""myboolean"" : ""true"" }";
QueueClient queueClient = /* not seen here */;
brokeredMsg = new BrokeredMessage(payLoad) { ContentType = System.Net.Mime.MediaTypeNames.Text.Plain };
queueClient.Send(brokeredMsg);
Now I use Service Bus Explorer (4.0.104), and I see the message in the queue
The issue is that when my Logic App runs, its not seeing plain-text/json.
You can see it picked up the content-type.
But it garbly gooks the content itself.
Is there a way to get raw-text with this trigger?
Note, the documentation says:
let's look at the two Content-Types that don't require conversion or
casting that you can use in a logic app: application/json and
text/plain.
from :
https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-content-type
https://learn.microsoft.com/en-us/azure/connectors/connectors-create-api-servicebus
My C# console app packages.config (nothing to do with Logic Apps, but including for completeness)
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.WindowsAzure.ConfigurationManager" version="2.0.1.0" targetFramework="net45" />
<package id="WindowsAzure.ServiceBus" version="2.1.4.0" targetFramework="net45" />
</packages>
APPEND:
I needed to do two thing to get it to work
One:
I had to change the "sender" code slightly.
QueueClient queueClient = /* not seen here */;
string ct = System.Net.Mime.MediaTypeNames.Text.Plain;
/* see https://social.msdn.microsoft.com/Forums/en-US/8fbf2391-8440-46db-bb47-648daccf46fd/servicebus-output-json-is-being-wrapped-in-a-xml-header-in-logic-app?forum=azurelogicapps and https://abhishekrlal.com/2012/03/30/formatting-the-content-for-service-bus-messages/ */
string payLoad = #"{ ""myid"": ""1000"", ""mymessage"": ""1000 is great"" , ""myboolean"" : ""true"" }";
brokeredMsg = new BrokeredMessage(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(Convert.ToString(payLoad))), true) { ContentType = ct };
queueClient.Send(brokeredMsg);
And I used the hint Derek Li gave me.
I've accepted his answer as the-answer, but PLEASE NOTE I had to do slightly more than he suggested. The code above has the urls for the reason I changed the sender code.
In a nutshell, the constructor for BrokeredMessage that I was using was choosing a specific serializer for me.
BrokeredMessage(Object)
Initializes a new instance of the BrokeredMessage class from a given object by
using DataContractSerializer with a binary XmlDictionaryWriter.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.servicebus.messaging.brokeredmessage.-ctor?view=azureservicebus-4.1.1#Microsoft_ServiceBus_Messaging_BrokeredMessage__ctor
and after I figured out the answer, I found this SOF answer:
Azure Service Bus Serialization Type
You can use expression #base64ToString(triggerBody()?['ContentData'])" to convert it to string.
Let's say I have an Atom entry like this:
<entry xmlns:custom="http://custom.xsd">
<title>test</title>
<custom:solution>42</custom:solution>
</entry>
If I load the entry into Apache Abdera, I get a nice org.apache.abdera.model.Entry instance. And I can now conveniently access all standard Atom elements with getters.
But how would I read the value 42 from the custom:solution element?
You can use something like:
for (Element element : (List<Element>)entry.getExtensions(" <UrI for custom namespace>")) {
System.out.println(element.getText());// gives you 42
}
All,
I try to load the FreeMarker template from database in the Smooks configuration file and use the build-ins INTERPRET to parse the string as template. However, the output is exactly the template I stored in the database.
The following is part of the Smooks configuration file:
....
<resource-config selector="hs:TravelerProfile">
<resource>org.milyn.delivery.DomModelCreator</resource>
</resource-config>
<db:executor executeOnElement="hs:TravelerProfile" datasource="StagingDS">
<db:statement>select freeMarker_template from template_lookup where agencyid='111';
</db:statement>
<db:resultSet name="mytemplate" />
</db:executor>
<ftl:freemarker applyOnElementNS="www.travel.com" applyOnElement="TravelerProfile">
<ftl:template>
< !--
<#assign templateSource = r"${mytemplate[0].freeMarker_template}">
<#assign inlineTemplate = [templateSource, "myInlineTemplate"]?interpret>
<#inlineTemplate/>
-- >
</ftl:template>
</ftl:freemarker>
.....
The template I stored in the database is like following:
<#ftl ns_prefixes={"D":"www.hhs.gov/travel"}>
<?xml version="1.0" encoding="UTF-8"?>
<po:PoHeadersInterfaceCollection xmlns:po="https://www.travel.com/xmlns/financial/po112007.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.travel.com/xmlns/financial/po112007.xsd">
<po:PoHeadersInterface>
<po:interfaceSourceCode>VendorName</po:interfaceSourceCode>
<po:poLinesInterfaceCollection>
<po:PoLinesInterface>
<po:PoDistributionsInterfaceCollection>
<po:PoDistributionsInterface>
<po:destinationOrganizationId>${TravelerProfile.TravelerOfficeCode}
</po:destinationOrganizationId>
</po:PoDistributionsInterface>
</po:PoDistributionsInterfaceCollection>
</po:PoLinesInterface>
</po:poLinesInterfaceCollection>
</po:PoHeadersInterface>
</po:PoHeadersInterfaceCollection>
====================================
For some reason, the output is exactly the above template itself. "${TravelerProfile.TravelerOfficeCode}" has not been evaluated! Please help!!!
Thank you!!!
Agnes
Sine mytemplate[0].freeMarker_template returns the template source code itself (or at least I assume that), and since you are using a raw string literal (r"..."), the source code of your template will be literally ${mytemplate[0].freeMarker_template}, which is then evaluated by ?interpret to the template source code. The corrected template would be:
<#assign inlineTemplate = [mytemplate[0].freeMarker_template, "myInlineTemplate"]?interpret>
<#inlineTemplate/>
which can be also written as:
<#([mytemplate[0].freeMarker_template, "myInlineTemplate"]?interpret) />
or if you don't need the "myInlineTemplate" template name:
<#mytemplate[0].freeMarker_template?interpret />
i'm parsing an xml with my extjs but it returns only one of the five components.
only the first one of the five components.
Ext.regModel('Card', {
fields: ['investor']
});
var store = new Ext.data.Store({
model: 'Card',
proxy: {
type: 'ajax',
url: 'xmlformat.xml',
reader: {
type: 'xml',
record: 'investors'
}
},
listeners: {
single: true,
datachanged: function(){
Ext.getBody().unmask();
var items = [];
store.each(function(rec){
alert(rec.get('investor'));
});
and my xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<investors>
<investor>Active</investor>
<investor>Aggressive</investor>
<investor>Conservative</investor>
<investor>Day Trader</investor>
<investor>Very Active</investor>
</investors>
<events>
<event>3 Month Expiry</event>
<event>LEAPS</event>
<event>Monthlies</event>
<event>Monthly Expiries</event>
<event>Weeklies</event>
</events>
<prices>
<price>$0.5</price>
<price>$0.05</price>
<price>$1</price>
<price>$22</price>
<price>$100.34</price>
</prices>
</root>
wen i run the code only "Active" comes out. . . .
i know that i'm doing something wrong but i'm not sure what....
please help . . . . .
Every thing was fine execpt that my xml format should be like this:
Active
3 Month Expiry
$0.5
Aggressive
LEAPS
$0.05
Conservative
Monthlies
$1
Day Trader
Monthly Expiries
$22
Very Active
Weeklies
$100.34
<?xml version="1.0" encoding="UTF-8"?>
<main>
<root>
<investor>Active</investor>
<event>3 Month Expiry</event>
<price>$0.5</price>
</root>
<root>
<investor>Aggressive</investor>
<event>LEAPS</event>
<price>$0.05</price>
</root>
<root>
<investor>Conservative</investor>
<event>Monthlies</event>
<price>$1</price>
</root>
<root>
<investor>Day Trader</investor>
<event>Monthly Expiries</event>
<price>$22</price>
</root>
<root>
<investor>Very Active</investor>
<event>Weeklies</event>
<price>$100.34</price>
</root>
</main>
You need to visit the sencha.com tutorial on how to use XML with a grid.
XML Grid Sample
You should take not of how to properly structure your XML so that it can be consumed by a data store.
The Ext XML grid needs to be configured to look for the repeating elements to map to each record in your store/grid. You had it configured for investors, of which there is only 1. Then you mapped a field for investor and it is just grabbing the first one that it encounters for the "column" of that "row".
The repeating element for your "rows" in the grid should be investor, not investors.
Change: record: 'investors'
to: record: 'investor'