2016-09-08 7 views
0

Моя цель состоит в том, чтобы пройти через XML-файл (объект DOM в памяти) и удалить все элементы, которые содержат данный атрибут, но не содержат определенного значения. Поэтому я хочу вернуть xpath, который будет идентифицировать все такие элементы для удаления, в этом случае, php.XPath - требуется значение атрибута, если оно существует

Представитель макета XML:

<root> 
    <pages> 
     <page required_distribution="customers, internal, vendors"> 
      <id>ID of page</id> 
      <name>Name of page with limited scope</name> 
      <more>more stuff</more> 
     </page> 
     <page> 
      <id>ID of next page</id> 
      <name>Name of next page which has unlimited scope</name> 
      <more>More stuff, other elements, etc.</more> 
     </page> 
    </pages> 
    <buttons> 
     <button> 
      <id>button ID</id> 
      <text>button text</text> 
     </button> 
     <button required_distribution="customers, vendors"> 
      <id>button ID with limited distribution</id> 
      <text>button text</text> 
     </button> 
    </buttons> 
    <innerhtmlblocks> 
     <!-- Represents elements that are inner html and pulled in directly 
      without additional XSLT parsing, except to remove the control attribute --> 
     <innerhtmlblock id="blockid"> 
      This is a content page, wherein there is innerhtml such as 
      <img src="./image.png" /> images and other elements can be 
      included in free form. Theoretically, though, I want to be 
      able to show certain 
      <div required_distribution="internal"> 
       content only to certain versions. 
      </div> 
      <div required_distribution="vendor, customers"> 
       content that varies by version. 
      </div> 
     </innerhtmlblock> 
    </innerhtmlblocks> 
</root> 

XSLT обеспечит преобразование из XML в HTML; Я хочу отфильтровать элементы до того, как XSLT произойдет, так что я получаю результирующий XML с фиктивным распределением «internal», выбирая и удаляя все узлы, которые не удовлетворяют моим требованиям.

<root> 
    <pages> 
     <page required_distribution="customers, internal, vendors"> 
      <id>ID of page</name> 
      <name>Name of page with limited scope</name> 
      <more>more stuff</more> 
     </page> 
     <page> 
      <id>ID of next page</id> 
      <name>Name of next page which has unlimited scope</name> 
      <more>More stuff, other elements, etc.</more> 
     <page> 
    </pages> 
    <buttons> 
     <button> 
      <id>button ID</id> 
      <text>button text</text> 
     </button> 
    </buttons> 
    <innerhtmlblocks> 
     <!-- Represents elements that are inner html and pulled in directly 
      without additional XSLT parsing, except to remove the control attribute --> 
     <innerhtmlblock id="blockid"> 
      This is a content page, wherein there is innerhtml such as 
      <img src="./image.png" /> images and other elements can be 
      included in free form. Theoretically, though, I want to be 
      able to show certain 
      <div required_distribution="internal"> 
       content only to certain versions. 
      </div> 
    </innerhtmlblocks> 
</root> 

В этом случае все элементы, которые имеют @required_distribution должны быть проверены, и если $ requiredval («внутренний») не появляется, то этот узел должен быть удален.

Ближайшая идея я пришел (courtesty обмена стека) является:

//*[@required_distribution and not(contains(@required_distribution,$requiredval))] 

Я также попытался

//*[@required_distribution]/[contains(@required_distribution,$requiredval)] 

и

//*[@required_distribution]/@required_distribution[contains(string(),$requiredval] 

, но ни к чему помогло. Я также пробовал варианты node(), self :: и т. Д., Но они были одинаково бесплодны (и, вероятно, недостаточно написаны, чтобы сделать их бесполезными).

После того, как я могу это сделать, я буду удалять атрибут управления (ы) с помощью XPath, который является единственным, я знаю работы:

//*[@required_distribution] 

В общем, мой вопрос, как я могу выбрать все элементы, где данный атрибут существует, но не содержит заданную строку?

ответ

0

Включите запятую после внутреннего

//*[@required_distribution and not(contains(@required_distribution, 'internal,'))] 

Значения атрибутов разделяются пробелами, а не запятыми. Вот почему contains не находит 'internal'.

+0

У меня нет функциональных причин, требующих запятых - в то время это имело смысл в моей голове, и я думал, что contains() - это функция типа instring. Благодаря! Мое отсутствие апострофов вокруг строки «внутренняя» тоже отбросило ее - я исправил это, и он работает. – Nick

+1

Я не вижу причины, по которой вам нужно включить запятую после 'internal' внутри кавычек. Напротив: если вам нужна запятая, вы пропустите те случаи, когда «internal» является последним (или единственным) значением, указанным в списке. –

+0

Я согласен - это не имело бы смысла из-за потери значений, когда «внутренний» был в конце. Однако по той причине, что @Federico упомянул, наличие запятой в теге испортило это. Я просто вытащил запятые и решил проблему. – Nick

0

Следующие должны работать:

//*[@required_distribution and not(contains(@required_distribution, 'internal'))]

+0

Спасибо! Мне не хватало апострофов вокруг строки «внутреннее», а также использовало запятые, в которых я не должен был. – Nick

Смежные вопросы