Web.Config Transform xml comments - xpath

How can I either select a comment or insert a comment using Web.config transforms?
Nowhere can I find any information on this.
I am trying to do either:
1) Insert a piece of xml (<serviceAuthorization impersonateCallerForAllOperations="true"/>) before an existing comment in the Web.config
OR
2) Insert a comment and xml at the end of a set of siblings:
As far as I can tell the Web.config transforms do not support xPath axes, I have tried a number of them to try and insert a node before the first comment:
<serviceAuthorization impersonateCallerForAllOperations="true" xdt:Transform="InsertBefore(/configuration/system.serviceModel/behaviors/serviceBehaviors/behavior[#name='behaviorOne']/serviceMetadata/preceding::comment()[1])"/>
<serviceAuthorization impersonateCallerForAllOperations="true" xdt:Transform="InsertBefore(/configuration/system.serviceModel/behaviors/serviceBehaviors/behavior[#name='behaviorOne']/child::node()[1]"/>
I have tried a few others, but you get the idea. I just get an error when previewing the transform.
I also can't seem to find any information on how to insert a comment. Am I missing something?

I believe that transformations are limited to operating on elements or attributes. At least, none of the documentation on xdt:Transform mentions anything that could be used to add a comment.
As for the Locator, there does seem to be some support for axes as I was able to use the following:
<spring >
<objects xmlns="http://www.springframework.net">
<object >
<constructor-arg index="0" type="System.Uri" value="https://example.com/test" xdt:Locator="Condition(../#name='requestConfig' and #index='0')" xdt:Transform="SetAttributes(value)"/>
</object>
</objects>
when operating on the following:
<spring >
<objects xmlns="http://www.springframework.net">
<object name="requestConfig" type="Example.Namespace.RequestConfig, Example" singleton ="true">
<constructor-arg index="0" type="System.Uri" value="https://example.com/production"/>
<constructor-arg index="1" value="45000"/>
</object>
</objects>
As you can see, the above uses the parent axis in order to match the element to be transformed.

Bit late to the party but for those googling I found a bit of a workaround - if you insert a node it inserts any comments inside the node, obviously you need to remove it first. Ie:
<customErrors xdt:Transform="Remove" />
<customErrors mode="On" defaultRedirect="Hub/Error" xdt:Transform="Insert">
<!-- comment -->
</customErrors>
The downside is that it destroys the child nodes but I try and put the comment as low as possible to alleviate the damage.

Related

XSD Verify Element has at least one of the attributes specified

Using XSD schema validation 1.0 I want to verify an element has at least one attribute specified.
For example, a simple element like this:
<foo a="1" b="2" c="3" />
I want to verify that at least attribute b or c is specified. But note that both can also be specified--they're not mutually exclusive.
I tried using a key along the lines of:
<xs:key name="AttributeSpecified">
<xs:selector xpath="." />
<xs:field xpath="#b|#c" />
</xs:key>
but it fails when both attributes are specified (because multiple results are returned).
Can it be done?
This is not possible in XSD 1.0. It might be possible in XSD 1.1.
I am a fan of XML Schema, but I would not choose it for this type of validation. You might be able to make it work using XSD1.1 but if your requirements became just a little more complex you could end up with some horrible-looking constraints.
On the other hand, an XPath expression can elegantly express any constraint you can think of, and you would not need to bend the language to make it work.

FHIR Profile/StructDef: How are children (sub-elements) of a named slice tied to the slice?

I'm trying to figure out how to fully specify a sliced element. If I'm reading the spec right, nameReference is the only place where a "sub element" of a slice can declare which slice it's "on".
So, if telecom is sliced by use and system and I want to specify a constraint on home phone, I have to fix use and system to those values and then add my constraints on that slice.
Consider:
Resource Example ElementDefinition attributes
================================ =====================================================================
<Patient> name="Patient"
... snip ...
<telecom> name="HomePhone"
<system value="phone" /> name="HomePhone.system", nameReference="HomePhone", fixedCode="phone"
<use value="home" /> name="HomePhone.use" , nameReference="HomePhone", fixedCode="home"
<value value="5551234567" /> name="HomePhone.value" , nameReference="HomePhone"
</telecom>
... snip ...
</Patient>
In most examples, it appears that a dotted notation of Name has been used (as I've placed in the example). But the specification doesn't require this and provides no format that could be reliably parsed.
The problem is: nameReference and fixed[x] are mutually exclusive. What's the correct way to handle this??
Repetitions in an instance don't "declare" what slice they're part of. They simply declare the appropriate value for what ever element(s) are the discriminator for the slicing process. nameReference isn't involved at all. On the definition side, association is simply handled by name. So HomePhone.system is associated with HomePhone simply by the name and by sequential proximity. The dot-notation is required. We could probably be a bit more explicit about that though, so feel free to submit a change request.

How to get XmlInputParser work with self-closing XML tags?

I am trying to load XML files from SE data dump* into HDFS using MapReduce. These XML files consist of a number of <row> elements (enclosed in a top-level "category"), like so:
<badges>
<row Id="1" UserId="1" Name="Organizer" Date="2009-07-15T06:51:46.370" />
<row Id="2" UserId="3" Name="Organizer" Date="2009-07-15T06:51:46.387" />
<row Id="4" UserId="1" Name="Autobiographer" Date="2009-07-15T06:51:46.447" />
...
</badges>
I want each "row" to be processed by a separate map() function, and have configured org.apache.mahout.classifier.bayes.XmlInputFormat's start and end tags as below:
Configuration config = new Configuration();
config.set(XmlInputFormat.START_TAG_KEY, "<row>");
config.set(XmlInputFormat.END_TAG_KEY, "</row>");
However, this fails to parse the XML file, because the <row> element is self-closing. How do I get this to work, without artificially "closing" the self-closing tags?
Linking to SE blog rather than directly to the data dump, to prevent dead link in case location changes in future.
This is a somewhat ugly hack. Change the START_TAG_KEY and END_TAG_KEY as below:
config.set(XmlInputFormat.START_TAG_KEY, "<row");
config.set(XmlInputFormat.END_TAG_KEY, "/>");
The "keys" are being used like delimiters, and accept any string, rather than just XML tags. Not a "clean" solution, and may stop working on future implementations, but it gets the work done now.
Note: I figured it out while I was midway through posting the question. This seems rather obvious in hindsight, but I decided to go ahead with the post anyway, so that someone may find it useful in future.

how to read text in child elements if the parent element's name has dots in freemarker

I have an xml document that I would like to parse using freemarker. The XML document itself was auto generated using SAX in my smooks script. This smooks script created the following XML with element names derived from the actual java package names that I have in my workspace.
<map>
<entry>
<string>RunReportMsg</string>
<com.web.ws.messages.v1__2.RunReportMsg>
<analyticsReport>
<columns>
<com.web.ws.objects.v1__2.ReportColumn>
<dataType>
<id>
<id>10</id>
</id>
</dataType>
</com.web.ws.objects.v1__2.ReportColumn>
</columns>
<analyticsReport>
</com.web.ws.messages.v1__2.RunReportMsg>
</entry>
</map>
A similar question has been posted on this site about this. But I cannot figure out how this would solve my problem.
Access XML elements with names containing a period/dot in FreeMarker templates
I know how to access "RunReportMsg" text in the element "string".
${map.entry.string}
How do I access data in the following child element using dotted notation in freemarker? As the element "com.web.ws.messages.v1__2.RunReportMsg" has multiple periods, I am not sure how to traverse down through further child elements. I need a way to find out the number in the following "id" element.
<id>10</id>
I read the documentation on expressions in freemarker site on ".vars". I am not sure if this applies to my case.
Any help is deeply appreciated.
You can use this syntax:
${map.entry["com.web.ws.messages.v1__2.RunReportMsg"].analyticsReport.columns["com.web.ws.objects.v1__2.ReportColumn"].dataType.id.id}

Wrapping an XML element with its ancestor nodes/tags

I can't navigate the XML doc programmatically and I need an one-line XPath solution for reasons I describe at the end.
I am working with an XML schema that looks something like the one below. (This is something I have to use as-is.)
<Root>
<!-- Child 1 -->
<Child>
<Name>Joe</Name>
<Age>12</Age>
</Child>
<!-- Child 2 -->
<Child>
<Name>Mike</Name>
<Age>25</Age>
</Child>
<!-- Child 3 -->
<Child>
<Name>Jane</Name>
<Age>20</Age>
</Child>
</Root>
Assuming I'm already at the "Joe" node (i.e. the Name element inside Child 1), I need to define an XPath query that will "wrap" that node as follows:
<Root>
<!-- Child 1 -->
<Child>
<Name>Joe</Name>
<Age>12</Age>
</Child>
</Root>
I've tried various combinations of ancestor, string-join, concat, etc., but can't seem to find the solution that "wraps" the element correctly. (The way I was using ancestor was returning all Child nodes, for example, which is not what I need.)
Some other considerations:
The solution has to be a one-line XPath query, if that's possible (for reasons given below).
It has to be generic enough to work for any Child element (i.e., it can't assume that I'm always at the first or second or third child, for example).
From the example above, you can see that I don't actually need the actual Root node per-se, just its tag (i.e. I don't want all Child nodes under it). However, I do need the actual Child node (so that I get the Name and Age).
NOTE: For what it's worth, I can't actually navigate the XML programmatically. I am using a library (whose code I cannot change) in which I have to define everything in terms of one-line XPath queries within a configuration file. It will essentially navigate through all of the Name elements, so my solution has to work from that point.
XPath is a query language.
This, among other things means that the evaluation of an XPath expression never modifies the XML document.
So, the answer is: Modifying an XML document or creating a new document cannot be done using only XPath.
Such transformations are very easy and natural to specify with XSLT.

Resources