I'm trying to search through my Android project's XML files for objects that do not contain a certain object.
My set of objects looks like this:
<View
android:id="#+id/obstacle3"
android:layout_width="#dimen/obstacle_width"
android:layout_height="#dimen/obstacle_width"
android:background="#drawable/play_portal"
android:layout_below="#+id/obstacle36"
android:layout_toRightOf="#+id/obstacle29"
ads:brother="#+id/obstacle21"
/>
<View
android:id="#+id/obstacle3"
android:layout_width="#dimen/obstacle_width"
android:layout_height="#dimen/obstacle_width"
android:background="#drawable/play_portal"
android:layout_below="#+id/obstacle36"
android:layout_toRightOf="#+id/obstacle29"
/>
<View
android:id="#+id/obstacle3"
android:layout_width="#dimen/obstacle_width"
android:layout_height="#dimen/obstacle_width"
android:background="#drawable/play_portal"
android:layout_below="#+id/obstacle36"
android:layout_toRightOf="#+id/obstacle29"
ads:brother="#+id/obstacle21"
/>
With this search,
<View(\s+[^>]*?)ads([^>]*?/>) I can find all Views that contain ads:brother attribute, but I want the inverse; I want to find all Views that do not contain ads:brother attribute.
I've tried numerous things to no avail. What am I doing wrong here?
__Insert mandatory disclaimer "don't parse xml with regex" here__
<View([^>](?!ads))*?\/>
See it in action
The idea is to check that after each matched character there is no ads following, thus there is no ads in the entire match.
Related
What I am want to do is the same as this question.
The question could be divided into two-part.
First, Referencing to string in a custom XML file, thanks to the author of the question I mentioned above, this is solved.
Second, and is what I am asked, How to show an autocomplete popup dialog to select string when typing string like #string.
The question I mentioned has been asked about four years ago and I think the second part of the question is also need to solve, without autocomplete, typing string is so unbearable.
I try to do like XSD - Autocomplete and Validate XML in IDE, but I failed.
I have made it.
Roughly speaking, Create a schema of the XML and apply it. With a schema, the IDE could know your XML file structure and then give the popup dialog to show available options.
If you are newer at schema, don't afraid, because it is easy to understand and we could use Android Studio to generate it.
How to generate a schema file?
First, select your XML file, then key ctrl + shift + A to show the actions input dialog. Key in "Generate" you will find the action of Generate XSD file from XML file ..., magically a schema for your XML will be created for you.
And then apply it to your XML, and how?
I think I don't have to show the concrete steps since it's unnecessary. (Probably it may be nobody to see it and I write here mainly leave a note for me)
I encounter the biggest problem is how to define the restriction for the attribute. how I make it?
In my Gradle task, I use the java parser parser the file of R.java and get a list of String then create .xsd file to create a restriction type. Then, in the main '.xsd' file, include it, and apply the type to the attribute.
// file: cartype.xml our target
<Car>
<item boxId="1" bandName="#string/xxx" ... />
</Car>
// define a type for the attriute of bandName and tell what can be select
<xs:simpleType name="AndroidStringType">
<xs:restriction >
<xs:enumeration value="1" />
<xs:enumeration value="2" />
<xs:enumeration value="3" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="itemType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="boxId"/>
// apply the type to the attribute
<xs:attribute type="AndroidStringType" name="bandName"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
Trying to dynamically set the layout using databinding but I can't seem to get the ternary operator to work right. Must be missing escape character or something.
<include
android:id="#+id/setting"
bind:settingsViewModel="#{settingsViewModel}"
layout="#{settingsViewModel.configFlag ? #layout/settings_v1 :#layout/settings_v2}" />
Seems simple enough but errors with "****/ data binding error ****msg:included value ... must start with #layout/. "
The answer to this is that you cannot do this. Layout is called before and so this logic cannot be done before hand.
Provided a similar xml as follows,
<data>
<train>
<departing>
<schedule>
<time />
<time />
<time />
</schedule>
<locations>
<name>
<name/>
<name>
<name/>
</locations>
</departing>
</train>
<train>
<departing>
<schedule>
<time />
<time />
<time />
</schedule>
<locations>
<name>
<name/>
<name>
<name/>
</locations>
</departing>
</train>
</data>
For simplicity, I have omitted the attributes. The data I'm interested in is the following:
Attributes in every train element.
Elements within a particular train element.
In reality, this xml would be much longer(10+ times). Since this is for android, I want to choose the lightest way to parse this xml. DOM is not my option since it stores too many elements I don't need.
I have been thinking of using SAX. I would use boolean variable to skip unnecessary elements, but I still have to at least reach all of the train elements before I break out of parsing (by throwing exception).
Am I looking at the right approach with SAX for this?
I would first try the XPath option since that will solve your problem with the least amount of code.
I have no knowledge about the internal Android XPath implementation details, but if those turns out to be too heavy weight, I would look at the pull parser packages before submitting to SAX. Pull parsing is usually more straight forward to work with compared to SAX.
I know how the switch statement works but I don't know what this means (R.id.webbutton). Can anyone please explain what it is and also what is TAG?
Is there any guide for the beginners? I mean absolute beginners.
IDs and Tags
IDs
Views may have an integer id associated with them. These ids are
typically assigned in the layout XML files, and are used to find
specific views within the view tree. A common pattern is to:
Define a Button in the layout file and assign it a unique ID.
<Button
android:id="#+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/my_button_text"/>
From the onCreate method of an Activity, find the Button
Button myButton = (Button) findViewById(R.id.my_button);
View IDs need not be unique throughout the tree, but it is good
practice to ensure that they are at least unique within the part of
the tree you are searching.
Tags
Unlike IDs, tags are not used to identify views. Tags are essentially
an extra piece of information that can be associated with a view. They
are most often used as a convenience to store data related to views in
the views themselves rather than by putting them in a separate
structure.
Tags may be specified with character sequence values in layout XML as either a single tag using the android:tag attribute or multiple tags using the child element:
<View ...
android:tag="#string/mytag_value" />
<View ...>
<tag android:id="#+id/mytag"
android:value="#string/mytag_value" />
</View>
Tags may also be specified with arbitrary objects from code using setTag(Object) or setTag(int, Object).
Id is id of your xml's components [may be views like textview,edittext... or viewgroup like linearlayout ,relativelayout... or anything else] in xml simply you can get reference to them in java code by saying
(R.id."id of your view in xml")
but firstly you should use setContentView(R.layout."name of xml file in layout/res in your project")
this xml file which you want to use it's components .
TAG i use it when i want to show message in logcat [tool in eclipse you can watch your app messages when it is running] by saying String TAG= yourclassname.class.getsimpleName();
and use it in Log.d(TAG,"any string here"+some variable in my class i want to know it's value in a particular time when app running );
i hope that i made it clear to you .
Start with the tutorials. (If you are so absolutely a beginner that you don't have a development environment set up yet, then start with Installing the SDK.)
When you use the console log facility in Android, the first argument to the logging methods is a tag, which can be used to filter logcat output. A typical programming style is:
public class Something {
private static final String TAG = "Something";
public void aMethod() {
Log.i(TAG, "Entered aMethod");
}
. . .
}
That's what TAG is.
Resource IDs are explained in the tutorial. When you define a resource in XML, Android generates a class called R with nested classes for different kinds of resources (R.id, R.string, R.layout, etc.). Each of those nested classes has a constant for each resource of that type. R.id.webbutton might be generated from a layout file that has a button with attribute android:id="#+id/webbutton". This is all explained in the tutorials.
Say I have two Activities in an Android application, EditPerson and EditEmployee.
It would seem natural to have the EditPerson Activity be a base class for the EditEmployee Activity and define methods that marshal data to and from the Views defined in the layout. The EditPerson Activity's implementation would push (for example) the "Name" field to and from an EditText element. The EditEmployee versions would call the base class version, and then marshal its own specialized fields (say a tax id, etc.).
To facilitate the shared code, both activities would have to have a layout resource that defines one or more pairs of EditText elements that share the same id. i.e. in layout\edit_person.xml there would be:
<EditText android:id="#+id/name_editor" />
And then in layout\edit_employee.xmlthere would be something like:
<EditText android:id="#+id/name_editor" />
<EditText android:id="#+id/tax_id_editor" />
<!-- etc. -->
Since the "Employee" is a "Person", and there are fields in common (marshaled via inheritance), it would seem as if the id assigned ("name_editor" in the above example) only has to be unique within the scope of an activity (or layout?).
From my testing, this appears to work, but I am paranoid that there would be a unintentional side effect to this approach and use of ambiguous layout element ids. Can anyone confirm that this is a safe practice and/or point out how it will eventually blow up my application? Has anyone ever done similar things?
It's common and ok to use. Especially intended when you want to reuse code/classes, but use different layouts.