XPath - 要求属性的值(如果存在)

时间:2016-09-08 16:20:20

标签: xml xslt xpath

我的目标是浏览XML文件(内存中的DOM对象)并删除包含给定属性但不包含特定值的所有元素。因此,我想返回一个xpath,它将识别所有要删除的元素,在本例中为php。

代表性的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。

<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 (“internal”),则应删除该节点。

我最近的想法(对堆栈交换的态度)是:

//*[@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]

总之,我的问题是如何选择给定属性存在但不包含给定字符串的所有元素?

2 个答案:

答案 0 :(得分:0)

以下内容应该有效:

def create(self, request, args, *kwargs): location_id = self.request.data.get("user_location_id") location = Location.objects.get(pk=location_id) serializer = self.get_serializer(data=request.data, partial=True) serializer.is_valid(raise_exception=True) serializer.save(user_location_id=location) self.perform_create(serializer) response = { "status" : status.HTTP_201_CREATED, "message" : "User Created.", "response" : serializer.data } return Response(response)

答案 1 :(得分:0)

在内部

之后加入逗号
//*[@required_distribution and not(contains(@required_distribution, 'internal,'))]

属性值由空格分隔,而不是逗号。这就是为什么contains找不到&#39;内部&#39;

的原因