I'm building an XSD to generate JAXB objects in Java. Then I ran into this:
<TotalBugs>
<Bug1>...</Bug1>
<Bug2>...</Bug2>
...
<BugN>...</BugN>
</TotalBugs>
How do I build a sequence of elements where the index of the sequence is in the element name? Specifically, how do I get the 1 in Bug1
You don't want to do it in this way, XML has a top-down order by nature. Consequently, you don't have to enumerate yourself:
<totalBugs>
<bug><!-- Here comes 1st bug --></bug>
<bug><!-- Here comes 2nd bug --></bug>
...
<bug><!-- Here comes last bug --></bug>
</totalBugs>
You can access the 1st bug node in the list by the XPath expression:
/totalBugs/bug[1]
Note, indexes start by W3C standard at 1. Please refer to for further readings to w3schools.
I'm pretty sure XSD won't support what you need. However you can use <xsd:any> for that bit of the schema, then use something lower-level than JAXB to generate the XML for that particular part. (I think your generated classes will have fields like protected List<Element> any; which you can fill in using DOM).
Related
Example A:
I need to make below object as dynamic as possible, in order to have robust/flexibility. this is an upload button, but the value of element tend to change for time being:
xpath="//input[#id='**j_idt162:input**'] ,
so i tried below :
xpath="//input[#id='j_idt[0-9],{1,4}:input']
Example B:
i have lists of caseIDs, i only need to get one of it. doesnt matter from the top or down. instead of using static below
xpath = "//a[contains(.,'3131')]")
i tried this
xpath = "//a[contains(.,'^[0-9]{1,5}$')]"), "index:=0"
none of above is working, Example A, i tried to only give 4 digit number but range is dynamic.
Example B, I'm trying to let it pick up only first one link with with limited to range 5, for instance (12345)'
Thanks in advance for answering
HTML node example
It's not possible to use Regex in XPath 1.0, and most browsers support XPath 1.0 only.
You'd better use prefix and suffix in class or id. Then use start-with() and end-with() or contains() to find the element.
For example,
//*[starts-with(#id, 'sometext') and ends-with(#id, '_text')]
Check this answer.
Let's say I have the following XML document:
<Offices>
<Office name="P">
<Counter>1000</Counter>
</Office>
<Office name="K">
<Counter>1006</Counter>
</Office>
</Offices>
With that document I need to perform the following in Java:
Parse the XML.
Get the value of Counter given a certain value for a name attribute.
Update the XML with a new value for Counter for exactly this Office.
For 2. I have considered using XPath but editing/updating the XML seems to be not that easy this way.
How could I go through the XML finding a certain office name and update its counter? The XML itself won't be large, only something like 20 office entries max.
You can try looking at this answer:
https://stackoverflow.com/a/5059411/1571550
It seems pretty straightforward and generic solution.
The XSD schema I am working with, calls for either an international or domestic address:
"/mns:PhysicalAddress/mns:DomesticAddress/mns:City"
or
"/mns:PhysicalAddress/mns:InternationalAddress/mns:City"
It is being used as a parameter in a Java method as in XMLUtils.BuildField(Document doc, String xpath).
I know I can go straight to the Java object that created that doc and use the auto-generated beans to query elements, but I prefer remaining within the concise realm of XPath. Is this possible?
If so, how do I write an XPath expression selects mns:City regardless of whether it is international or domestic address?
Note: This in Java, not Javascript, HTML or XSLT, so I don't think <xsl:if> is relevant here.
You could go with finding all Cities that have either parent:
//mns:City[(parent::mns:DomesticAddress|parent::mns:InternationalAddress)]
If you need to also ensure that the address is in the physical address:
//mns:City[(parent::mns:DomesticAddress|parent::mns:InternationalAddress)[parent::mns:PhysicalAddress]]
Alternatively, instead of reversing the hierarchy, you do a * and check the name:
/mns:PhysicalAddress/*[name()="mns:DomesticAddress" or name()="mns:InternationalAddress"]/mns:City
Depending in the precise structure of your XML,
/mns:PhysicalAddress/*/mns:City
may be enough, if that pulls in too much then the clearest option is probably just to use the two alternatives you already have, separated by a |:
/mns:PhysicalAddress/mns:DomesticAddress/mns:City | /mns:PhysicalAddress/mns:InternationalAddress/mns:City
Or slightly more concise but (in my opinion) less clear:
/mns:PhysicalAddress/*[self::mns:DomesticAddress | self::mns:InternationalAddress]/mns:City
I am comparing my XML files using the sample code (Possible duplicate) in the below post by acdcjunior - Best way to compare 2 XML documents in Java
I see the below error from the assert test.
Expected presence of doctype declaration 'null' but was 'not null' - comparing at to <!DOCTYPE plist PSECTOR " ..........
Can someone please guide me what I can do to fix this?
Okay, I found the solution here - http://xmlunit.sourceforge.net/userguide/XMLUnit-Java.pdf
For efficiency reasons a Diff stops the comparison process as soon as the first difference is found. To get all the differences
between two pieces of XML an instance of the DetailedDiff class, a subclass of Diff, is required. Note that a Detailed
Diff is constructed using an existing Diff instance.
For future readers, here is the solution (also in the link - Pg 9) -
DifferenceListener myDifferenceListener = new IgnoreTextAndAttributeValuesDifferenceListener();
Diff myDiff = new Diff(expectedXML, actualXML);
myDiff.overrideDifferenceListener(myDifferenceListener);
Assert.assertTrue("test XML matches control skeleton XML", myDiff.similar());
From the link again,
The DifferenceEngine class generates the events that are passed to a DifferenceListener implementation as two
pieces of XML are compared. Using recursion it navigates through the nodes in the control XML DOM, and determines which
node in the test XML DOM qualifies for comparison to the current control node. The qualifying test node will match the control
node’s node type, as well as the node name and namespace (if defined for the control node).
what do I obtain if I call IndexReader.getTermFrequenciesVector(...) on an index created with TermVector.YES option?
The documentation already answers this, as Xodorap notes in a comment.
The TermFreqVector object returned can retrieve which terms (words produced by your analyzer) a field contains and how many times each of those terms exists within that field.
You can cast the returned TermFreqVector to the interface TermPositionVector if you index the field using TermVector.WITH_OFFSETS, TermVector.WITH_POSITIONS or TermVector.WITH_POSITIONS_OFFSETS. This gives you access to GetTermPositions with allow you to check where in the field the term exists, and GetOffsets which allows you to check where in the original content the term originated from. The later allows, combined with Store.YES, highlighting of matching terms in a search query.
There are different contributed highlighters available under Contrib area found at the Lucene homepage.
Or you can implement proximity or first occurrence type score contributions. Which highlighting won't help you with at all.