escape xml characters

This commit is contained in:
REAndroid 2023-01-18 13:49:39 -05:00
parent 291628b140
commit 4566824570
10 changed files with 61 additions and 112 deletions

View File

@ -162,7 +162,7 @@ import java.util.*;
} }
} }
private void addStyleElement(XMLElement element){ private void addStyleElement(XMLElement element){
styleList.add(element.buildTextContent()); styleList.add(element.buildTextContent(false));
} }
} }

View File

@ -96,9 +96,7 @@ public class XMLFileEncoder {
} }
} }
private void buildAttributes(XMLElement element, ResXmlElement resXmlElement){ private void buildAttributes(XMLElement element, ResXmlElement resXmlElement){
int count=element.getAttributeCount(); for(XMLAttribute attribute:element.listAttributes()){
for(int i=0;i<count;i++){
XMLAttribute attribute=element.getAttributeAt(i);
if(attribute instanceof SchemaAttr){ if(attribute instanceof SchemaAttr){
continue; continue;
} }
@ -176,9 +174,7 @@ public class XMLFileEncoder {
resXmlElement.calculatePositions(); resXmlElement.calculatePositions();
} }
private void ensureNamespaces(XMLElement element, ResXmlElement resXmlElement){ private void ensureNamespaces(XMLElement element, ResXmlElement resXmlElement){
int count=element.getAttributeCount(); for(XMLAttribute attribute:element.listAttributes()){
for(int i=0;i<count;i++){
XMLAttribute attribute = element.getAttributeAt(i);
String prefix = SchemaAttr.getPrefix(attribute.getName()); String prefix = SchemaAttr.getPrefix(attribute.getName());
if(prefix==null){ if(prefix==null){
continue; continue;
@ -194,12 +190,10 @@ public class XMLFileEncoder {
idBuilder.buildTo(resXmlBlock.getResXmlIDMap()); idBuilder.buildTo(resXmlBlock.getResXmlIDMap());
} }
private void searchResIds(ResIdBuilder idBuilder, XMLElement element){ private void searchResIds(ResIdBuilder idBuilder, XMLElement element){
int count=element.getAttributeCount(); for(XMLAttribute attribute : element.listAttributes()){
for(int i=0;i<count;i++){
XMLAttribute attribute = element.getAttributeAt(i);
addResourceId(idBuilder, attribute); addResourceId(idBuilder, attribute);
} }
count=element.getChildesCount(); int count=element.getChildesCount();
for(int i=0;i<count;i++){ for(int i=0;i<count;i++){
searchResIds(idBuilder, element.getChildAt(i)); searchResIds(idBuilder, element.getChildAt(i));
} }

View File

@ -46,7 +46,6 @@ class XMLValuesEncoderAttr extends XMLValuesEncoderBag{
resValueBag.getEntryBlock().setPublic(true); resValueBag.getEntryBlock().setPublic(true);
} }
private void encodeAttributes(XMLElement parentElement, ResValueBag resValueBag){ private void encodeAttributes(XMLElement parentElement, ResValueBag resValueBag){
int count=parentElement.getAttributeCount();
ResValueBagItemArray bagItemArray = resValueBag.getResValueBagItemArray(); ResValueBagItemArray bagItemArray = resValueBag.getResValueBagItemArray();
int bagIndex=0; int bagIndex=0;
@ -66,8 +65,7 @@ class XMLValuesEncoderAttr extends XMLValuesEncoderBag{
bagIndex++; bagIndex++;
for(int i=0;i<count;i++){ for(XMLAttribute attribute : parentElement.listAttributes()){
XMLAttribute attribute = parentElement.getAttributeAt(i);
String name = attribute.getName(); String name = attribute.getName();
if("name".equals(name) || "formats".equals(name)){ if("name".equals(name) || "formats".equals(name)){
continue; continue;

View File

@ -36,15 +36,44 @@ class XMLValuesEncoderStyle extends XMLValuesEncoderBag{
ResValueBagItemArray itemArray = resValueBag.getResValueBagItemArray(); ResValueBagItemArray itemArray = resValueBag.getResValueBagItemArray();
for(int i=0;i<count;i++){ for(int i=0;i<count;i++){
XMLElement child=parentElement.getChildAt(i); XMLElement child=parentElement.getChildAt(i);
ResValueBagItem item = itemArray.get(i);
String name=child.getAttributeValue("name");
int id=decodeUnknownAttributeHex(name);
if(id!=0){
String value = child.getTextContent();
if(ValueDecoder.isReference(value)){
item.setTypeAndData(ValueType.REFERENCE,
getMaterials().resolveReference(value));
}else {
ValueDecoder.EncodeResult encodeResult = ValueDecoder.encodeGuessAny(value);
if(encodeResult!=null){
item.setTypeAndData(encodeResult.valueType, encodeResult.value);
}else {
item.setValueAsString(value);
}
}
continue;
}
EntryBlock attributeEntry=getMaterials() EntryBlock attributeEntry=getMaterials()
.getAttributeBlock(child.getAttributeValue("name")); .getAttributeBlock(name);
if(attributeEntry==null){ if(attributeEntry==null){
throw new EncodeException("Unknown attribute name: '"+child.toText() throw new EncodeException("Unknown attribute name: '"+child.toText()
+"', for style: "+parentElement.getAttributeValue("name")); +"', for style: "+parentElement.getAttributeValue("name"));
} }
encodeChild(parentElement.getChildAt(i), attributeEntry, itemArray.get(i)); encodeChild(child, attributeEntry, item);
} }
} }
private int decodeUnknownAttributeHex(String name){
if(name.length()==0||name.charAt(0)!='@'){
return 0;
}
name=name.substring(1);
if(!ValueDecoder.isHex(name)){
return 0;
}
return ValueDecoder.parseHex(name);
}
private void encodeChild(XMLElement child, EntryBlock attributeEntry, ResValueBagItem bagItem){ private void encodeChild(XMLElement child, EntryBlock attributeEntry, ResValueBagItem bagItem){
bagItem.setId(attributeEntry.getResourceId()); bagItem.setId(attributeEntry.getResourceId());

View File

@ -94,15 +94,9 @@ public class XMLAttribute extends XMLNode{
public void setValue(String val){ public void setValue(String val){
mValue= XMLUtil.escapeXmlChars(val); mValue= XMLUtil.escapeXmlChars(val);
} }
public boolean isEmpty(){
return XMLUtil.isEmpty(getName());
}
@Override @Override
public boolean write(Writer writer, boolean newLineAttributes) throws IOException { public boolean write(Writer writer, boolean newLineAttributes) throws IOException {
if(isEmpty()){
return false;
}
writer.write(getName()); writer.write(getName());
writer.write("=\""); writer.write("=\"");
String val= XMLUtil.trimQuote(getValue()); String val= XMLUtil.trimQuote(getValue());
@ -114,9 +108,6 @@ public class XMLAttribute extends XMLNode{
} }
@Override @Override
public String toText(int indent, boolean newLineAttributes) { public String toText(int indent, boolean newLineAttributes) {
if(isEmpty()){
return null;
}
StringWriter writer=new StringWriter(); StringWriter writer=new StringWriter();
try { try {
write(writer); write(writer);
@ -131,16 +122,12 @@ public class XMLAttribute extends XMLNode{
if(name==null){ if(name==null){
name=""; name="";
} }
name=getClass().getName()+name;
return name.hashCode(); return name.hashCode();
} }
@Override @Override
public boolean equals(Object obj){ public boolean equals(Object obj){
if(obj instanceof XMLAttribute){ if(obj instanceof XMLAttribute){
XMLAttribute attr=(XMLAttribute)obj; XMLAttribute attr=(XMLAttribute)obj;
if(isEmpty()){
return attr.isEmpty();
}
return getName().equals(attr.getName()); return getName().equals(attr.getName());
} }
return false; return false;

View File

@ -26,7 +26,7 @@ import java.util.*;
public class XMLElement extends XMLNode{ public class XMLElement extends XMLNode{
static final long DEBUG_TO_STRING=500; static final long DEBUG_TO_STRING=500;
private String mTagName; private String mTagName;
private final List<XMLAttribute> mAttributes = new ArrayList<>(); private final LinkedHashMap<String, XMLAttribute> mAttributes = new LinkedHashMap<>();
private final List<XMLElement> mChildElements = new ArrayList<>(); private final List<XMLElement> mChildElements = new ArrayList<>();
private final List<XMLComment> mComments = new ArrayList<>(); private final List<XMLComment> mComments = new ArrayList<>();
private final List<XMLText> mTexts = new ArrayList<>(); private final List<XMLText> mTexts = new ArrayList<>();
@ -94,7 +94,7 @@ public class XMLElement extends XMLNode{
if(exist!=null){ if(exist!=null){
exist.setValue(schemaAttr.getValue()); exist.setValue(schemaAttr.getValue());
}else { }else {
addAttributeNoCheck(schemaAttr); addAttribute(schemaAttr);
} }
} }
} }
@ -254,8 +254,8 @@ public class XMLElement extends XMLNode{
mComments.clear(); mComments.clear();
mTexts.clear(); mTexts.clear();
} }
public List<XMLAttribute> listAttributes(){ public Collection<XMLAttribute> listAttributes(){
return mAttributes; return mAttributes.values();
} }
public int getChildesCount(){ public int getChildesCount(){
return mChildElements.size(); return mChildElements.size();
@ -272,12 +272,6 @@ public class XMLElement extends XMLNode{
public int getAttributeCount(){ public int getAttributeCount(){
return mAttributes.size(); return mAttributes.size();
} }
public XMLAttribute getAttributeAt(int index){
if(index>=mAttributes.size()){
return null;
}
return mAttributes.get(index);
}
public String getAttributeValue(String name){ public String getAttributeValue(String name){
XMLAttribute attr=getAttribute(name); XMLAttribute attr=getAttribute(name);
if (attr==null){ if (attr==null){
@ -303,48 +297,11 @@ public class XMLElement extends XMLNode{
throw new XMLException(ex.getMessage()+": "+" '"+toString()+"'"); throw new XMLException(ex.getMessage()+": "+" '"+toString()+"'");
} }
} }
public boolean getAttributeValueBool(String name, boolean def){
XMLAttribute attr=getAttribute(name);
if (attr==null){
return def;
}
if(!attr.isValueBool()){
return def;
}
return attr.getValueBool();
}
public boolean getAttributeValueBool(String name) throws XMLException {
XMLAttribute attr=getAttribute(name);
if (attr==null || !attr.isValueBool()){
throw new XMLException("Expecting boolean for attr <"+name+ "> at '"+toString()+"'");
}
return attr.getValueBool();
}
public XMLAttribute getAttribute(String name){ public XMLAttribute getAttribute(String name){
if(XMLUtil.isEmpty(name)){ return mAttributes.get(name);
return null;
}
for(XMLAttribute attr:mAttributes){
if(name.equals(attr.getName())){
return attr;
}
}
return null;
} }
public XMLAttribute removeAttribute(String name){ public XMLAttribute removeAttribute(String name){
if(XMLUtil.isEmpty(name)){ return mAttributes.remove(name);
return null;
}
XMLAttribute attr=getAttribute(name);
if(attr==null){
return null;
}
int i=mAttributes.indexOf(attr);
if(i<0){
return null;
}
mAttributes.remove(i);
return attr;
} }
public XMLAttribute setAttribute(String name, int value){ public XMLAttribute setAttribute(String name, int value){
return setAttribute(name, String.valueOf(value)); return setAttribute(name, String.valueOf(value));
@ -364,7 +321,7 @@ public class XMLElement extends XMLNode{
}else{ }else{
attr=new XMLAttribute(name,value); attr=new XMLAttribute(name,value);
} }
addAttributeNoCheck(attr); addAttribute(attr);
}else { }else {
attr.setValue(value); attr.setValue(value);
} }
@ -382,20 +339,15 @@ public class XMLElement extends XMLNode{
if(attr==null){ if(attr==null){
return; return;
} }
if(XMLUtil.isEmpty(attr.getName())){ String name = attr.getName();
if(XMLUtil.isEmpty(name)){
return; return;
} }
XMLAttribute exist=getAttribute(attr.getName()); XMLAttribute exist = mAttributes.get(name);
if(exist!=null){ if(exist!=null){
return; return;
} }
mAttributes.add(attr); mAttributes.put(name, attr);
}
private void addAttributeNoCheck(XMLAttribute attr){
if(attr==null || attr.isEmpty()){
return;
}
mAttributes.add(attr);
} }
public void sortChildes(Comparator<XMLElement> comparator){ public void sortChildes(Comparator<XMLElement> comparator){
if(comparator==null){ if(comparator==null){
@ -403,12 +355,6 @@ public class XMLElement extends XMLNode{
} }
mChildElements.sort(comparator); mChildElements.sort(comparator);
} }
public void sortAttributes(Comparator<XMLAttribute> comparator){
if(comparator==null){
return;
}
mAttributes.sort(comparator);
}
public XMLElement getParent(){ public XMLElement getParent(){
return mParent; return mParent;
} }
@ -534,13 +480,13 @@ public class XMLElement extends XMLNode{
if(!hasTextContent()){ if(!hasTextContent()){
return null; return null;
} }
return buildTextContent(); return buildTextContent(true);
} }
public String buildTextContent(){ public String buildTextContent(boolean unEscape){
StringWriter writer=new StringWriter(); StringWriter writer=new StringWriter();
try { try {
for(XMLNode node:getChildNodes()){ for(XMLNode node:getChildNodes()){
node.buildTextContent(writer); node.buildTextContent(writer, unEscape);
} }
writer.flush(); writer.flush();
writer.close(); writer.close();
@ -548,7 +494,7 @@ public class XMLElement extends XMLNode{
} }
return writer.toString(); return writer.toString();
} }
void buildTextContent(Writer writer) throws IOException { void buildTextContent(Writer writer, boolean unEscape) throws IOException {
writer.write("<"); writer.write("<");
writer.write(getTagName()); writer.write(getTagName());
appendAttributes(writer, false); appendAttributes(writer, false);
@ -558,7 +504,7 @@ public class XMLElement extends XMLNode{
} }
writer.write('>'); writer.write('>');
for(XMLNode node:getChildNodes()){ for(XMLNode node:getChildNodes()){
node.buildTextContent(writer); node.buildTextContent(writer, unEscape);
} }
if(hasChildNodes()){ if(hasChildNodes()){
writer.write("</"); writer.write("</");
@ -611,10 +557,7 @@ public class XMLElement extends XMLNode{
} }
private boolean appendAttributes(Writer writer, boolean newLineAttributes) throws IOException { private boolean appendAttributes(Writer writer, boolean newLineAttributes) throws IOException {
boolean addedOnce=false; boolean addedOnce=false;
for(XMLAttribute attr:mAttributes){ for(XMLAttribute attr:listAttributes()){
if(attr.isEmpty()){
continue;
}
if(addedOnce){ if(addedOnce){
if(newLineAttributes){ if(newLineAttributes){
writer.write(XMLUtil.NEW_LINE); writer.write(XMLUtil.NEW_LINE);

View File

@ -78,7 +78,7 @@ public abstract class XMLNode {
boolean hasChildNodes(){ boolean hasChildNodes(){
return mChildNodes.size()>0; return mChildNodes.size()>0;
} }
void buildTextContent(Writer writer) throws IOException{ void buildTextContent(Writer writer, boolean unEscape) throws IOException{
} }
public boolean write(Writer writer) throws IOException { public boolean write(Writer writer) throws IOException {

View File

@ -21,7 +21,7 @@ import java.io.Writer;
public class XMLText extends XMLNode{ public class XMLText extends XMLNode{
private String text; private String text;
public XMLText(String text){ public XMLText(String text){
this.text=text; this.text=XMLUtil.escapeXmlChars(text);
} }
public XMLText(){ public XMLText(){
this(null); this(null);
@ -44,8 +44,8 @@ public class XMLText extends XMLNode{
this.text=XMLUtil.escapeXmlChars(text); this.text=XMLUtil.escapeXmlChars(text);
} }
@Override @Override
void buildTextContent(Writer writer) throws IOException{ void buildTextContent(Writer writer, boolean unEscape) throws IOException{
writer.write(this.text); writer.write(getText(unEscape));
} }
@Override @Override
public boolean write(Writer writer, boolean newLineAttributes) throws IOException { public boolean write(Writer writer, boolean newLineAttributes) throws IOException {

View File

@ -29,7 +29,7 @@ public class XMLUtil {
if(str==null){ if(str==null){
return null; return null;
} }
if(!PATTERN_ESCAPE.matcher(str).matches()){ if(str.indexOf('&')<0 && str.indexOf('<')<0 && str.indexOf('>')<0){
return str; return str;
} }
str=str.replaceAll("&amp;", "&"); str=str.replaceAll("&amp;", "&");

View File

@ -35,9 +35,7 @@ package com.reandroid.xml;
if(element==null){ if(element==null){
return; return;
} }
int max=element.getAttributeCount(); for(XMLAttribute exist : element.listAttributes()){
for(int i=0;i<max;i++){
XMLAttribute exist=element.getAttributeAt(i);
setAttribute(exist.getName(), exist.getValue()); setAttribute(exist.getName(), exist.getValue());
} }
} }
@ -104,7 +102,7 @@ package com.reandroid.xml;
return 0; return 0;
} }
@Override @Override
void buildTextContent(Writer writer) throws IOException { void buildTextContent(Writer writer, boolean unEscape) throws IOException {
} }
} }