I'm brand new to XML, but not SQL. I have data structured by our app vendor as follows that I'm trying to load up into a table:
<windowsets>
<windows>
<question>
<id Value="81b25d-9385-sk3" />
<displayname Value="Thermal Break" />
<answername Value="Yes" />
</question>
<question>
<id Value="73v32k-2743-fd9" />
<displayname Value="Panel Profile" />
<answername Value="Medium Stille" />
</question>
</windows>
</windowsets>
Through other posts here I found and got as far as creating:
select
t.x.value('(id [#Value]/text())[1]','varchar(100)') QuestionID,
t.x.value('(displayname [#Value]/text())[1]','varchar(255)') DisplayName,
t.x.value('(answername [#Value]/text())[1]','varchar(255)') AnswerName
from #xmlData.nodes('//windowsets/windows/question') as T(X)
But it returns nulls for all columns, and I'm guessing that's because it's expecting the format of:
<displayname>Panel Profile</displayname>
So being the XML novice and all the searching I've done hasn't help me understand how to change the code to pull it when the value is buried in node (not even sure of correct terminology I'm so new).
THANK you for your help!
It is called attributes.
To read attributes from xml try something like this
select
t.x.value('(id/#Value)[1]','varchar(100)') QuestionID,
t.x.value('(displayname/#Value)[1]','varchar(255)') DisplayName,
t.x.value('(answername/#Value)[1]','varchar(255)') AnswerName
from #xmlData.nodes('//windowsets/windows/question') as T(X)
This is not an new answer, just some explanation and to much for a comment:
The part within the square brackets is called predicate and is kind of a filter. Your expression
displayname [#Value]/text())[1]
will read the text() of <displayname> and will check, if the attribute #Value exists. Anyway, there is no element's text, so it will return NULL.
You must navigate down the path like .../displayname/#Value if you want to read the attribute's value.
This answer shows some examples how XML deals with empty members.
Related
The IBM Watson Dialog API documentation on the following page refers to an entityRules node for expert dialog designers to extract the system-programmed entities but does not say anything else about the node:
http://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/dialog/reference_nodes.shtml#reference_entityRules
Is there more detailed documentation on how this node can be used?
You can use entities to create your own data type. So in the doc, we see the example
<entities>
<entity name="currency" entityExample="dollar" entityType="GENERIC">
<value name="USD" value="USD">
<grammar>
<item>dollar </item>
<item>buck</item>
</grammar>
</value>
<value name="EUR" value="EUR">
<grammar>
<item>euro</item>
<item>eur</item>
<item>european buck</item>
</grammar>
</value>
<entityRules></entityRules>
</entity>
</entities>
This "currency" entity has a couple of value types (USD and EUR) but it could be extended to have more rows with more examples of each value. We could also add more values (say YEN, AUD etc or Japanese Yen, Australia Dollar etc).
The next thing would be to utilize the entity in a variation. So you could add a variation in an Input node, example:
I want to convert (currency) to (currency) tomorrow!
You can use any entities in a variation by simply including brackets around it.
You can also assign entity info into a profile variable so you can later access it and utilize it in your Dialog logic. Example variation:
I want to convert (currency)={CURRENCY1} to (currency)={CURRENCY2} tomorrow!
In this example, CURRENCY1 and CURRENCY2 are profile variables, that at run time, contain the entity match info.
Hope this helps.
Can any one provide me simple example in camel with JAXB using spring XML? I searched on net but did not find anything.
I just want to create simple Student class with fields name, id and convert it into xml.
Not sure what in particular you're struggling with, but here are some snippets:
<util:map id="jaxbNamespacePrefixMap">
<!-- In my case, we dont want a prefix for our namespace; YMMV -->
<entry key="http://www.nmcourts.gov" value=""/>
</util:map>
<marshal>
<jaxb prettyPrint="true" contextPath="generated.gov.nmcourts.ecitation.shared.odyssey"
partClass="generated.gov.nmcourts.ecitation.shared.odyssey.NMCitationEFileBatch" partNamespace="EFileBatch"
namespacePrefixRef="jaxbNamespacePrefixMap"/>
</marshal>
<unmarshal>
<jaxb prettyPrint="true" contextPath="generated.gov.nmcourts.ecitation.shared.odyssey"
partClass="generated.gov.nmcourts.ecitation.shared.odyssey.NMCitationEFileBatch"
partNamespace="EFileBatch" namespacePrefixRef="jaxbNamespacePrefixMap" />
</unmarshal>
What do you need exactly?
http://camel.apache.org/jaxb shows perfectly well how to marshal to xml via spring.
I need to filter the response of a SOAP web-service. Since SOAP is based on XML, I am thinking about using libxml2, but I am not able to understand how to write an XPath expression to achieve the desired result.
At the end of the message you'll find an example of the response, where two NotficationMessages are sent, one has a topic tns1:RuleEngine/LineDetector/Crossed , the other one has topic tns1:RuleEngine/CellMotionDetector/Motion .
I am trying to write the following XPath expressions:
match any NotficationMessage whose topic is tns1:RuleEngine/LineDetector/Crossed
match any NotficationMessage whose topic is tns1:RuleEngine//.
match any NotficationMessage whose topic is everything but tns1:RuleEngine//.
All the examples I found match on attributes, not the content of child elements.
So I'm asking.
are this kinds of matching doable with libxml2 or with XPath in general?
can you please give me a hint about writing the XPath expressions?
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:wstop="http://docs.oasis-open.org/wsn/t-1"
xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
xmlns:tet="http://www.onvif.org/ver10/events/wsdl"
xmlns:tns1="http://www.onvif.org/ver10/topics"
xmlns:tt="http://www.onvif.org/ver10/schema">
<SOAP-ENV:Header>
<wsa:Action> http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/PullMessagesResponse
</wsa:Action>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<tet:PullMessagesResponse>
<tet:CurrentTime>
2008-10-10T12:24:58
</tet:CurrentTime>
<tet:TerminationTime>
2008-10-10T12:25:58
</tet:TerminationTime>
<wsnt:NotificationMessage>
<wsnt:Topic Dialect="http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet">
tns1:RuleEngine/LineDetector/Crossed
</wsnt:Topic>
<wsnt:Message>
<tt:Message UtcTime="2008-10-10T12:24:57.321Z">
<tt:Source>
<tt:SimpleItem Name="VideoSourceConfigurationToken"
Value="1"/>
<tt:SimpleItem Name="VideoAnalyticsConfigurationToken"
Value="2"/>
<tt:SimpleItem Value="MyImportantFence1" Name="Rule"/>
</tt:Source>
<tt:Data>
<tt:SimpleItem Name="ObjectId" Value="15" />
</tt:Data>
</tt:Message>
</wsnt:Message>
</wsnt:NotificationMessage>
<wsnt:NotficationMessage>
<wsnt:Topic Dialect="http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet">
tns1:RuleEngine/CellMotionDetector/Motion
</wsnt:Topic>
<wsnt:Message>
<tt:Message UtcTime= "2010-10-20T12:24:57.628">
<tt:Source>
<tt:SimpleItem Name="VideoSourceConfigurationToken" Value="1"/>
<tt:SimpleItem Name="VideoAnalyticsConfigurationToken" Value="1"/>
<tt:SimpleItem Name="Rule" Value="MotionInDefinedCells"/>
</tt:Source>
<tt:Data>
<tt:SimpleItem Name="IsMotion" Value="true"/>
</tt:Data>
</tt:Message>
</wsnt:Message>
</wsnt:NotficationMessage>
</tet:PullMessagesResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
All you need are basic XPath expressions using location paths and predicates:
match any NotficationMessage whose topic is tns1:RuleEngine/LineDetector/Crossed
//wsnt:NotificationMessage[wsnt:Topic = 'tns1:RuleEngine/LineDetector/Crossed']
match any NotficationMessage whose topic is tns1:RuleEngine//.
//wsnt:NotificationMessage[wsnt:Topic = 'tns1:RuleEngine//.']
match any NotficationMessage whose topic is everything but tns1:RuleEngine//.
//wsnt:NotificationMessage[wsnt:Topic != 'tns1:RuleEngine//.']
Not wanting to clog up the question, I've left out most of the code but I can put it in if it helps.
using Breeze 1.4.9 and Breeze.angular v.0.9.0
I have a simple model: a ChartDefinition has a single DataQuery, and that DataQuery has some parameters.
I have a breeze query:
var query = breeze.EntityQuery
.from("ChartDefinitions")
.expand(["DataQuery","DataQuery.Parameters"]);
//.noTracking();
I can see the server's response (i've replaced most of the simple properties with '...'):
[{"$id":"1","$type":"itaprm4.Domain.ChartDefinition, itaprm4","Id":1,"Title":"FirstChart", ... ,
"DataQuery":
{"$id":"2","$type":"itaprm4.Domain.DataQuery, itaprm4","Id":1, ... ,
"Parameters":
[{"$id":"3","$type":"itaprm4.Domain.DataQueryParameter, itaprm4","Id":1, ...}]
}
}
,{"$id":"4","$type":"itaprm4.Domain.ChartDefinition, itaprm4","Id":2,"Title":"ProjectBudgets", ... ,
"DataQuery":
{"$id":"5","$type":"itaprm4.Domain.DataQuery, itaprm4","Id":2, ... ,
"Parameters":[]
}
},
{"$id":"6","$type":"itaprm4.Domain.ChartDefinition, itaprm4","Id":3,"Title":"ProjectActuals", ... ,
"DataQuery":
{"$id":"7","$type":"itaprm4.Domain.DataQuery, itaprm4","Id":3, ... ,
"Parameters":
[{"$id":"8","$type":"itaprm4.Domain.DataQueryParameter, itaprm4","Id":2,"DataQueryId":3, ...},
{"$id":"9","$type":"itaprm4.Domain.DataQueryParameter, itaprm4","Id":3,"DataQueryId":3, ...}
]
}
}]
After the entities have been materialised though, that last DataQuery object ($id:7) has a parameters array but, it only contains the last parameter ($id:9).
Digging around in breeze.debug I saw that noTracking causes the materialisation code down a different path so tacked the noTracking() option onto the query. This results in both the paramters appearing in the materlised Parameters array. (I'm assuming that since breeze can materialise the object graph correctly, there isn't anything wrong with the code on the server? so I haven't included it in this question...)
I would simply keep the noTracking option on but, I'm registering a constructor function with breeze and it doesn't get called if noTracking is on.
store.registerEntityTypeCtor('ChartDefinition', ChartDefinition);
Is there something else I need to do to get the parameters array filled without the noTracking option?
Edit:
Another observation : without the noTracking option, the DataQueryParameter with $id:8 actually ends up in the parameters array of the DataQuery with $id:5
Turns out this had a lot to do with what was on the server!
Our nHibernate set-up was using a different name for the DataQueryId property on the DataQuery class (the devs in the team tell me there were some issues with updating entities and doing this solved that issue):
<class name="DataQuery" table="sys_DataQuery" dynamic-update="true" >
<id name="Id" column="DataQueryId" type="int" unsaved-value="0">
<generator class="identity" />
</id>
...
<bag name="Parameters" cascade="all-delete-orphan">
<key column="DataQueryId"/>
<one-to-many class="DataQueryParameter"/>
</bag>
</class>
<class name="DataQueryParameter" table="sys_DataQueryParameter" dynamic-update="true" >
...
<property name="DataQueryId" type="int" not-null="true" insert="true" update="true" />
...
</class>
With matching identifiers in the class definitions.
Changing the Id to DataQueryId solved my problem:
<class name="DataQuery" table="sys_DataQuery" dynamic-update="true" >
<id name="DataQueryId" column="DataQueryId" type="int" unsaved-value="0">
<generator class="identity" />
</id>
...
This seems to make sense; how would breeze know to match DataQueryParamter.DataQueryId to DataQuery.Id but, I have no idea why Breeze could correctly materialise the object graph with noTracking switched on though?
I have some XML to ingest into Solr, which sounds like a use case that is intended to be solved by the DataImportHandler. What I want to do is pull the column name from one XML attribute and the value from another attribute. Here is an example of what I mean:
<document>
<data ref="reference.foo">
<value>bar</value>
</data>
</document>
From this xml snippet, I want to add a field with name reference.foo and value bar. The DataImportHandler includes a XPathEntityProcessor for processing XML documents. I've tried using it and it works perfectly if I give it a known column name (e.g, <field column="ref" xpath="/document/data/#ref">) but have not been able to find any documentation or examples to suggest either how to do what I want, or that it cannot be done. So:
Can I do this using XPathEntityProcessor? If so, how?
If not, can I do this some other way with DataImportHandler?
Or am I left with writing my own import handler?
I haven't managed to find a way to do this without bringing in a transformer, but by using a simple ScriptTransformer I worked it out. It goes something like this:
...
<script>
function makePair(row) {
var theKey = row.get("theKey");
var theValue = row.get("theValue");
row.put(theKey, theValue);
row.remove("theKey");
row.remove("theValue");
return row;
}
</script>
...
<entity name="..."
processor="XPathEntityProcessor"
transformer="script:makePair"
forEach="/document"
...>
<field column="theKey" xpath="/document/data/#ref" />
<field column="theValue" xpath="/document/data/value" />
</entity>
...
Hope that helps someone!
Note, if your dynamicField is multivalued, you have to iterate over theKey since row.get("theKey") will be a list.
What you want to do is select the node keying on an attribute value.
From your example, you'd do this:
<field column="ref" xpath="/document/data[#ref='reference.foo']"/>