as3 поиск XML с несколькими элементами
Я пытаюсь найти этот документ XML в as3
<mineral>
<name>Calcite</name>
<color>White</color
<diaphaneity>Opaque</diaphaneity>
</mineral>
<mineral>
<name>Spangolite</name>
<color>Blue</color>
<color>Green</color>
<color>Blue Green</color>
<color>Dark Green</color>
<color>Emerald Green</color>
<diaphaneity>Transparent</diaphaneity>
<diaphaneity>Translucent</diaphaneity>
</mineral>
<mineral>
<name>Barite</name>
<color>Yellow</color>
<color>Honey</color>
<diaphaneity>Transparent</diaphaneity>
<diaphaneity>Translucent</diaphaneity>
<diaphaneity>Opaque</diaphaneity>
</mineral>
<mineral>
<name>Landauite</name>
<color>White</color>
<diaphaneity>Transparent</diaphaneity>
<diaphaneity>Translucent</diaphaneity>
</mineral>
<mineral>
<name>Sapphire</name>
<color>Blue</color>
<color>Blue green</color>
<diaphaneity>Transparent</diaphaneity>
<diaphaneity>Translucent</diaphaneity>
</mineral>
и сначала отфильтруйте результаты по цвету. Поэтому, если вы будете искать "Синий", вы получите результаты всех минералов, которые содержат "цветной" элемент, значение которого "Синий" (Спанголит и Сапфир).
Я загружаю в свой XML и создаю XMLList всех элементов.
var dataLoader:URLLoader = new URLLoader();
var xmlData:XML;
dataLoader.addEventListener(Event.COMPLETE, LoadComplete);
dataLoader.load(new URLRequest("mineralXML.xml"));
function LoadComplete(e:Event):void
{
xmlData = new XML(e.target.data);
ParseMinerals(xmlData);
}
function ParseMinerals(mineralXML:XML):void
{
var mineralList:XMLList = mineralXML.mineral;
trace(mineralList);
}
С помощью команды "trace(mineralList)" он успешно отследит весь XML-файл, и если я изменю его на "trace(xmlData.mineral.(Color == "White"));" затем он отслеживает все узлы этого элемента со значением "Белый".
<mineral>
<name>Calcite</name>
<color>White</color>
<diaphaneity>Opaque</diaphaneity>
</mineral>
<mineral>
<name>Landauite</name>
<color>White</color>
<diaphaneity>Transparent</diaphaneity>
<diaphaneity>Translucent</diaphaneity>
</mineral>
Однако, если я ищу синий вместо белого, он ничего не обнаруживает. Я предполагаю, что это потому, что минеральные узлы, содержащие элемент со значениями "Blue", также имеют несколько других значений цвета. Это проблема, которую я пытаюсь оценить.
Мне нужно иметь возможность искать цвет и извлекать все узлы, которые имеют одно из этих значений цвета, независимо от наличия других значений цвета.
2 ответа
Я фактически достиг этого с помощью следующего кода:
сначала я создал массив для результатов, которые будут содержаться, когда они определены, а также переменную, чтобы отметить, какой номер результата был в цикле
var resultArray:Array = new Array;
var resultNum:Number = 0;
Затем я сделал общий объект из данных XML
function ParseMinerals(mineralXML:XML):void
{
//create a var called memory and datatype it to SharedObject and name the
//file "attributes"
var memory:SharedObject = SharedObject.getLocal("attributes");
//create an XMLList containing the information in mineralXML.mineral
var mineralList:XMLList = mineralXML.mineral;
//save the data in mineralList to shared object
memory.data.mineralList = mineralList;
memory.flush();
}
вместо того, чтобы запускать код после загрузки xml в функцию ParseMinerals, я помещаю его в новую функцию под названием "поиск", которая запускается при нажатии кнопки "поиск".
function search(event:MouseEvent):void
{
//load shared file
var memory:SharedObject = SharedObject.getLocal("attributes");
//create a variable that is the length of the list of minerals
var len:int = memory.data.mineralList.length();
//create variables to temporarily store information regarding minerals color
//and name
var thisColor:String;
var thisName:String;
//create var that increments for each time you loop through a "mineral" node
for (var i:int = 0; i < len; i++) {
//create var that increments for each time you loop through a "color"
//element within a single "mineral" node
for (var c:int = 0; c < xmlData.mineral[i].color.length(); c++) {
//make thisColor equal to the current color that the for loop is on
thisColor = xmlData.mineral[i].color[c];
//make thisName equal to the current name that the for loop is on
thisName = xmlData.mineral[i].name;
//if the color that the for loop is currently on is equal to the
//color you are searching for...
if (thisColor == memory.data.mineralColor){
//... then put the name of that mineral into an array
resultArray.push(thisName);
//... add 1 to the current result number
resultNum ++;
//... and trace the current result number and the name of the
//... mineral corresponding to the color you are searching for
trace("Result #" + resultNum + ": " + (thisName));
}
}
}
//reset array
resultArray.length = 0;
//reset result number
resultNum = 0;
}
Я не уверен, что это самый эффективный способ достижения цели, но он работает. Если я выберу "White" из списка и нажму кнопку "Search", которую я сделал, программа проследит
Result #1: Calcite
Calcite
и если я ищу "синий", то программа отслеживает
Result #1: Spangolite
Result #2: Sapphire
Spangolite, Sapphire
Я надеюсь, что это поможет любому, кто пытается достичь аналогичной цели.
В вашем коде узел имеет только один узел в случае цвета == белый. В других случаях он имеет более одного узла. Попробуй так,
private function ParseMinerals(mineralXML:XML):void
{
var mineralList:XMLList = mineralXML.mineral;
for each (var mineral:XML in mineralList)
{
if(mineral.color.length()>1)
{
for each(var color in mineral.color)
{
if(color == "Green")
{
trace(mineral);
}
}
}
else
{
if(mineral.color == "White")
{
trace(mineral);
}
}
}